I have an ASP.NET Web API controller that I would have thought would operate asynchronously. The controller is designed to sleep 20 seconds for the first request, but service any subsequent requests immediately. So my anticipated timeline would be something like:
- Raise request 1.
- Raise request 2.
- Raise request 3.
- Request 2 returns.
- Request 3 returns.
- Wait ~20 seconds.
- Request 1 returns.
Instead, no requests return until request 1 is finished.
I can confirm (based on the debug outputs), that the entry thread and sleepy thread id are different. I've intentionally used TaskCreationOptions.LongRunning
to force the sleep onto a separate thread, but still the application refuses to service any new requests until that sleep has finished.
Am I missing something fundamental about how async Web API controllers really work?
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);
}
}