without run method espaƱol create await async c# transactionscope async-await

run - create async method c#



Obtener TransactionScope para trabajar con async/await (3)

async integrar async / await en nuestro bus de servicio. Implementé un SingleThreadSynchronizationContext basado en este ejemplo http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx .

Y funciona bien, excepto por una cosa: TransactionScope . Espero cosas dentro de TransactionScope y rompe el TransactionScope .

TransactionScope no parece funcionar bien con async / await , sin duda porque almacena cosas en el hilo usando ThreadStaticAttribute . Obtengo esta excepción:

"TransactionScope anidado incorrectamente".

Traté de guardar los datos de TransactionScope antes de poner en cola la tarea y restaurarla antes de ejecutarla, pero parece que no cambia nada. Y el código de TransactionScope es un desastre, por lo que es realmente difícil entender lo que sucede allí.

¿Hay alguna manera de hacerlo funcionar? ¿Hay alguna alternativa a TransactionScope ?


En .NET Framework 4.5.1, hay un conjunto de nuevos constructores para TransactionScope que toman un parámetro TransactionScopeAsyncFlowOption .

De acuerdo con MSDN, permite el flujo de transacciones a través de continuaciones de subprocesos.

Según entiendo, está destinado a permitir que escribas código como este:

// transaction scope using (var scope = new TransactionScope(... , TransactionScopeAsyncFlowOption.Enabled)) { // connection using (var connection = new SqlConnection(_connectionString)) { // open connection asynchronously await connection.OpenAsync(); using (var command = connection.CreateCommand()) { command.CommandText = ...; // run command asynchronously using (var dataReader = await command.ExecuteReaderAsync()) { while (dataReader.Read()) { ... } } } } scope.Complete(); }


Puede usar DependentTransaction creado por el método Transaction.DependentClone() :

static void Main(string[] args) { // ... for (int i = 0; i < 10; i++) { var dtx = Transaction.Current.DependentClone( DependentCloneOption.BlockCommitUntilComplete); tasks[i] = TestStuff(dtx); } //... } static async Task TestStuff(DependentTransaction dtx) { using (var ts = new TransactionScope(dtx)) { // do transactional stuff ts.Complete(); } dtx.Complete(); }

Administrar la concurrencia con DependentTransaction

http://adamprescott.net/2012/10/04/transactionscope-in-multi-threaded-applications/


Un poco tarde para obtener una respuesta, pero estaba teniendo el mismo problema con MVC4 y actualicé mi proyecto de 4.5 a 4.5.1 haciendo clic derecho en el proyecto, vaya a las propiedades. Seleccione la pestaña de la aplicación, cambie el marco de destino a 4.5.1 y use la transacción de la siguiente manera.

using (AccountServiceClient client = new AccountServiceClient()) using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { }