と.NET 4.6.1をターゲットとC#のテストプロジェクトは、私は、次の動作を取得:ここC#は(REPROテストで)のSynchronizationContextをクリア非同期メソッドで待つ
[TestClass]
public class AwaitTests
{
[TestMethod]
public void AsyncRemovingSyncContext_PartialFail()
{
Log("1");
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
Log("2");
HasAwait().Wait(); // The continuation in this method is on wrong thread
Log("5");
Assert.IsNotNull(SynchronizationContext.Current);
}
[TestMethod]
public async Task AsyncRemovingSyncContext_Fail()
{
Log("1");
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
Log("2");
await HasAwait();
Log("5"); // Issue is here - Sync Context is now null
Assert.IsNotNull(SynchronizationContext.Current);
}
public async Task HasAwait()
{
Log("3");
await Task.Delay(300);
Log("4");
}
private void Log(string text)
{
Console.WriteLine($"{text} - Thread {System.Threading.Thread.CurrentThread.ManagedThreadId} - {SynchronizationContext.Current}");
}
}
が出力されます。
AsyncRemovingSyncContext_PartialFail
1 - スレッド7 -
2 - スレッド7 - System.Threading.SynchronizationContext
3 - スレッド7 - System.Th reading.SynchronizationContext
4 - 糸8 -
5 - スレッド7 - System.Threading.SynchronizationContext
AsyncRemovingSyncContext_Error
1 - スレッド7 -
2 - スレッド7 - System.Threading.SynchronizationContext
3 - スレッド7 - System.Threading.SynchronizationContext
4スレッド8 -
5スレッド8 -
- アサルト例外スロー
私は他のテストを行いましたが、これまでの方法ではawait
キーワードの存在と同期コンテキストのクリアとの間に100%の相関があります。これには、非同期ラムダが含まれます。
await
が発生するとすぐに同期コンテキストが削除されるように見えるため、これは重要です。つまり、同じメソッドで2つのawait
を実行すると、2番目の継続はスレッドプールでのみ実行されます(同期コンテキストがない場合のデフォルトの動作)。
これはフレームワーク/コンパイラのバグですか、何か間違っていますか?詳細については
、私は誰かが一つの形態または別に尋ねると確信しているので、私は私がのためにasync
await
\サポートを有効にしたいのですが、私ができる場合、私は唯一のことを行うことができますActive Objectを持っていますお返事は私のActiveObjectSynchronizationContext
に発送されます。現時点では、それはクリアされているわけではありません。
私は既にthis question(と同様のUIコンテキスト4.0バグについて)を見てきましたが、4.6.1を実行してから非UIスレッドを使用しているので関連しません。
また、this other questionのアドバイスに従い、同期コンテキストがCreateCopy
を実装していることを確認しましたが、テストプロファイリングからメソッドが呼び出されていないことがわかります。
_ "私が何か間違ったことをやっている?" _ - それはあなたが[基本 'SynchronizationContext'クラスを考えている理由を説明するだろう場合には役立つだろう](http://referencesource.microsoft.com/#mscorlib/system/threading/synchronizationcontext.cs,8b34a86241c7b423)は、ここで何をしているのか正確には何もしていないはずです。 [ドキュメント](https://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext(v = vs.110).aspx)は完全にわかりやすいようです:_ "SynchronizationContextクラスはベースです同期を持たないフリースレッドのコンテキストを提供するクラスです。 "_ –
スレッドプールスレッド(' SynchronizationContext'クラスの動作)で継続が戻ってくるわけではありませんでしたが、同期コンテキストを設定していましたが、私は待っているし、同期コンテキストはnullです。私は最初にカスタムSynchronizationContextを使用してこの動作に気付きました。このSynchronizationContextはnullになり、 'Post'コマンドが送られなくなりました。私が見ていたエラーの最小の実例として、デフォルトの 'SynchronizationContext'クラスを使用しました。 –
_ "同期コンテキストを設定した後、同期コンテキストがヌル" _ - コンテキストはスレッドごとです(ドキュメント化されています)。コンテキストは「nullになりませんでした」。あなたは、あなたが設定したところから別のスレッドで実行するだけで、期待通りに実行します。また、そのスレッドのコンテキストは、期待通りにnullでした。 –