Estou tentando integrar async
/ await
em nosso barramento de serviço. Implementei um com SingleThreadSynchronizationContext
base neste exemplo http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx .
E ele funciona muito bem, exceto por uma coisa: TransactionScope
. Aguardo coisas dentro do TransactionScope
e quebre o TransactionScope
.
TransactionScope
não parece funcionar bem com o async
/ await
, certamente porque ele armazena coisas no thread usando ThreadStaticAttribute
. Eu recebo esta exceção:
"TransactionScope aninhado incorretamente.".
Tentei salvar os TransactionScope
dados antes de enfileirar a tarefa e restaurá-la antes de executá-la, mas parece que nada mudou. E o TransactionScope
código é uma bagunça, então é muito difícil entender o que está acontecendo lá.
Existe uma maneira de fazer funcionar? Existe alguma alternativa para TransactionScope
?
SingleThreadSynchronizationContext
para cada nível superiorTransactionScope
.Respostas:
No .NET Framework 4.5.1, há um conjunto de novos construtores para
TransactionScope
que recebam umTransactionScopeAsyncFlowOption
parâmetro.De acordo com o MSDN, ele permite o fluxo de transações entre continuações de thread.
Meu entendimento é que isso permite que você escreva um código como este:
fonte
Um pouco tarde para uma resposta, mas eu estava tendo o mesmo problema com MVC4 e atualizei meu projeto de 4.5 para 4.5.1 clicando com o botão direito do mouse em projeto ir para propriedades. Selecione a guia do aplicativo, altere a estrutura de destino para 4.5.1 e use a transação como segue.
fonte
Você pode usar DependentTransaction criado pelo método Transaction.DependentClone () :
Gerenciando simultaneidade com DependentTransaction
http://adamprescott.net/2012/10/04/transactionscope-in-multi-threaded-applications/
fonte
await Task.Delay(500)
este padrão, também falharáTransactionScope nested incorrectly
porque o TransactionScope mais externo (não mostrado no exemplo acima) sai do escopo antes que a tarefa filho seja concluída corretamente. Substituaawait
porTask.Wait()
e funciona, mas você perdeu os benefícios deasync
.