次のコードを検討してください。
public Task SomeAsyncMethod()
{
var tcs = new TaskCompletionSource();
... do something, NOT setting the TaskCompletionSource...
return tcs.Task
}
public void Callsite1()
{
await SomeAsyncMethod();
Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
public void Callsite2()
{
SomeAsyncMethod().ContinueWith((task) =>
{
Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
});
}
ある時点で、SomeAsyncMethodで作成されたTaskCompletionSourceがThreadPoolスレッドに設定されます。
Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
tcs.SetResult();
TaskCompletionSourceからのタスクが待機されると(Callsite1のように)、継続はSetResultを呼び出したスレッドで同期的に実行されます。(Callsite2のように)ContinueWithが呼び出されると、継続は別のスレッドで非同期に実行されます。
のように、configureawaitを呼び出すことは役に立ちません
public void Callsite1()
{
await SomeAsyncMethod().ConfigureAwait(true or false);
}
そして、これはこの質問のポイントでさえありません。SomeAsyncMethodの実装者として、SetResultを呼び出して未知の可能性のあるコードを呼び出したくありません。継続を常に非同期でスケジュールしたい。そして、私はawaitを適切に設定するために発信者に頼ることはできません(それがうまくいく場合でも)。
TaskCompletionSourceを構成して、タスクが待機中に同期的に継続を実行しないようにするにはどうすればよいですか?