Я пытаюсь интегрировать async
/ await
в нашу служебную шину. Я реализовал на SingleThreadSynchronizationContext
основе этого примера http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx .
И это работает отлично, за исключением одной вещи: TransactionScope
. Я жду хрень TransactionScope
и ломаюсь TransactionScope
.
TransactionScope
похоже, не очень хорошо работает с async
/ await
, конечно, потому что он хранит вещи в потоке, используя ThreadStaticAttribute
. Я получаю это исключение:
«TransactionScope неправильно вложен.».
Я пытался сохранить TransactionScope
данные перед постановкой задачи в очередь и восстановить их перед запуском, но, похоже, это ничего не меняет. А TransactionScope
код - это беспорядок, поэтому очень сложно понять, что там происходит.
Есть ли способ заставить его работать? Есть ли альтернатива TransactionScope
?
SingleThreadSynchronizationContext
для каждого верхнего уровняTransactionScope
.Ответы:
В .NET Framework 4.5.1 есть набор новых конструкторов
TransactionScope
, принимающихTransactionScopeAsyncFlowOption
параметр.Согласно MSDN, он обеспечивает поток транзакций через продолжения потоков.
Я понимаю, что он предназначен для того, чтобы вы могли писать такой код:
источник
Немного поздно для ответа, но у меня была такая же проблема с MVC4, и я обновил свой проект с 4.5 до 4.5.1, щелкнув правой кнопкой мыши проект, перейдите в свойства. Выберите вкладку приложения, измените целевую структуру на 4.5.1 и используйте транзакцию, как показано ниже.
источник
Вы можете использовать DependentTransaction, созданный методом Transaction.DependentClone () :
Управление параллелизмом с помощью DependentTransaction
http://adamprescott.net/2012/10/04/transactionscope-in-multi-threaded-applications/
источник
await Task.Delay(500)
этого шаблона, также произойдет сбой,TransactionScope nested incorrectly
потому что самый внешний TransactionScope (не показанный в приведенном выше примере) выходит из области видимости до того, как дочерняя задача завершится должным образом. Заменитеawait
на,Task.Wait()
и он заработает, но тогда вы потеряете все преимуществаasync
.