非同期で動作すると思っていたASP.NETWebAPIコントローラーがあります。コントローラは、最初の要求に対して20秒間スリープするように設計されていますが、後続の要求はすぐに処理します。したがって、私の予想されるタイムラインは次のようになります。
- リクエスト1を発生させます。
- リクエスト2を発生させます。
- リクエスト3を発生させます。
- リクエスト2が返されます。
- リクエスト3が返されます。
- 約20秒待ちます。
- リクエスト1が返されます。
代わりに、リクエスト1が終了するまでリクエストは返されません。
(デバッグ出力に基づいて)エントリスレッドとスリープスレッドIDが異なることを確認できます。私は意図的TaskCreationOptions.LongRunning
にスリープを別のスレッドに強制するために使用しましたが、それでもアプリケーションは、そのスリープが終了するまで新しい要求を処理することを拒否します。
非同期WebAPIコントローラーが実際にどのように機能するかについて基本的なことを見逃していますか?
public class ValuesController : ApiController
{
private static bool _firstTime = true;
public async Task<string> Get()
{
Debug.WriteLine("Entry thread id: {0}. Sync: {1}",
Thread.CurrentThread.ManagedThreadId,
SynchronizationContext.Current);
await LongWaitAsync();
return "FOOBAR";
}
private Task LongWaitAsync()
{
return Task.Factory.StartNew(() =>
{
if (_firstTime)
{
_firstTime = false;
Debug.WriteLine("Sleepy thread id: {0}. Sync: {1}",
Thread.CurrentThread.ManagedThreadId,
SynchronizationContext.Current);
Thread.Sleep(20000);
Debug.WriteLine("Finished sleeping");
}
},
CancellationToken.None,
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
}
}