Próbuję zintegrować async
/ await
z naszą magistralą usług. Zaimplementowałem na SingleThreadSynchronizationContext
podstawie tego przykładu http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx .
I to działa dobrze, z wyjątkiem jednej rzeczy: TransactionScope
. Czekam na rzeczy w środku TransactionScope
i to zepsuje TransactionScope
.
TransactionScope
nie wydaje się działać dobrze z async
/ await
, z pewnością dlatego, że przechowuje rzeczy w wątku przy użyciu ThreadStaticAttribute
. Mam ten wyjątek:
„TransactionScope zagnieżdżony nieprawidłowo.”.
Próbowałem zapisać TransactionScope
dane przed umieszczeniem zadania w kolejce i przywrócić je przed uruchomieniem, ale wydaje się, że nic to nie zmienia. A TransactionScope
kod to bałagan, więc naprawdę trudno jest zrozumieć, co się tam dzieje.
Czy jest sposób, aby to zadziałało? Czy jest jakaś alternatywa TransactionScope
?
SingleThreadSynchronizationContext
dla każdego najwyższego poziomuTransactionScope
.Odpowiedzi:
W .NET Framework 4.5.1 istnieje zestaw nowych konstruktorów,
TransactionScope
które pobierająTransactionScopeAsyncFlowOption
parametr.Według MSDN umożliwia przepływ transakcji przez kontynuacje wątków.
Rozumiem, że ma to umożliwić pisanie takiego kodu:
źródło
Trochę za późno na odpowiedź, ale miałem ten sam problem z MVC4 i zaktualizowałem mój projekt z 4.5 do 4.5.1, klikając prawym przyciskiem myszy projekt przejdź do właściwości. Wybierz kartę aplikacji, zmień platformę docelową na 4.5.1 i użyj transakcji w następujący sposób.
źródło
Możesz użyć DependentTransaction utworzonej przez metodę Transaction.DependentClone () :
Zarządzanie współbieżnością za pomocą DependentTransaction
http://adamprescott.net/2012/10/04/transactionscope-in-multi-threaded-applications/
źródło
await Task.Delay(500)
ten wzorzec, również zakończy się niepowodzeniem,TransactionScope nested incorrectly
ponieważ najbardziej zewnętrzny TransactionScope (nie pokazany w powyższym przykładzie) opuszcza zakres, zanim zadanie podrzędne zostanie poprawnie zakończone. Wymieńawait
sięTask.Wait()
i działa, ale potem straciłem korzyściasync
.