新しい async/await 機能を使用して、DB を非同期的に操作しようとしています。一部のリクエストは長くなる可能性があるため、キャンセルできるようにしたいです。私が直面している問題は、TransactionScope
明らかにスレッド アフィニティがあることです。タスクをキャンセルするとDispose()
、間違ったスレッドで実行されるようです。
具体的には、呼び出すと、 onを含む.TestTx()
次のメッセージが表示されます。AggregateException
InvalidOperationException
task.Wait ()
"A TransactionScope must be disposed on the same thread that it was created."
コードは次のとおりです。
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 ();
// ...
//}
}
}
}
更新: コメントアウトされた部分は、接続が開かれたときに非同期的に実行する必要があることを示していますが、問題を再現するためにそのコードは必要ありません。