Estoy tratando de usar la nueva función async/await para trabajar asincrónicamente con un DB. Como algunas de las solicitudes pueden ser largas, quiero poder cancelarlas. El problema al que me estoy enfrentando es que TransactionScope
aparentemente tiene una afinidad de subprocesos, y parece que al cancelar la tarea, su Dispose()
se ejecuta en un subproceso incorrecto.¿Cómo deshacerse de TransactionScope en async/await cancelable?
En concreto, cuando se llama a .TestTx()
me sale el siguiente AggregateException
contiene InvalidOperationException
en task.Wait()
:
"A TransactionScope must be disposed on the same thread that it was created."
Aquí está el código:
public void TestTx() {
var cancellation = new CancellationTokenSource();
var task = TestTxAsync (cancellation.Token);
cancellation.Cancel();
task.Wait();
}
private async Task TestTxAsync (CancellationToken cancellationToken) {
using (var scope = new TransactionScope()) {
using (var connection = new SqlConnection (m_ConnectionString)) {
await connection.OpenAsync (cancellationToken);
//using (var command = new SqlCommand (... , connection)) {
// await command.ExecuteReaderAsync();
// ...
//}
}
}
}
ACTUALIZADO: la parte comentada es mostrar que hay algo para estar hecho - asincrónicamente - con la conexión una vez que está abierta, pero ese código no es necesario para reproducir el problema.
¿Podría profundizar en su segundo punto? Mueve la creación a dónde? – chase
¿Está sugiriendo que solo abra la conexión de forma asincrónica y use llamadas de bloqueo para la carga de trabajo real? ¿O me estoy perdiendo algo de nuevo? – chase
Por el momento en su pregunta solo adquiere la conexión de forma asíncrona. He seguido su ejemplo, pero si actualiza su pregunta con cierta carga de trabajo real, entonces también puedo actualizar mi respuesta. – Maarten