J'essaye d'intégrer async
/ await
dans notre bus de service. J'ai implémenté un SingleThreadSynchronizationContext
basé sur cet exemple http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx .
Et cela fonctionne très bien, sauf pour une chose: TransactionScope
. J'attends des trucs à l'intérieur TransactionScope
et ça casse le TransactionScope
.
TransactionScope
ne semble pas jouer bien avec le async
/ await
, certainement parce qu'il stocke des choses dans le thread en utilisant ThreadStaticAttribute
. J'obtiens cette exception:
"TransactionScope imbriqué incorrectement.".
J'ai essayé de sauvegarder les TransactionScope
données avant de mettre la tâche en file d'attente et de la restaurer avant de l'exécuter, mais cela ne semble rien changer. Et le TransactionScope
code est un gâchis, il est donc vraiment difficile de comprendre ce qui se passe là-bas.
Y a-t-il un moyen de le faire fonctionner? Y a-t-il une alternative à TransactionScope
?
SingleThreadSynchronizationContext
pour chaque niveau supérieurTransactionScope
.Réponses:
Dans .NET Framework 4.5.1, il existe un ensemble de nouveaux constructeurs
TransactionScope
qui acceptent unTransactionScopeAsyncFlowOption
paramètre.Selon le MSDN, il permet le flux de transaction entre les continuations de thread.
Je crois comprendre que cela est censé vous permettre d'écrire du code comme celui-ci:
la source
Un peu en retard pour une réponse mais j'avais le même problème avec MVC4 et j'ai mis à jour mon projet de 4.5 à 4.5.1 en faisant un clic droit sur le projet aller aux propriétés. Sélectionnez l'onglet de l'application, changez le cadre cible en 4.5.1 et utilisez la transaction comme suit.
la source
Vous pouvez utiliser DependentTransaction créé par la méthode Transaction.DependentClone () :
Gestion de la concurrence avec DependentTransaction
http://adamprescott.net/2012/10/04/transactionscope-in-multi-threaded-applications/
la source
await Task.Delay(500)
ce modèle échouera égalementTransactionScope nested incorrectly
car le TransactionScope le plus à l'extérieur (non illustré dans l'exemple ci-dessus) quitte la portée avant que la tâche enfant ne se termine correctement. Remplacezawait
parTask.Wait()
et cela fonctionne, mais vous avez perdu les avantages deasync
.