On my server I have a route that generates a pdf for a user. When the generation takes longer than a specified amount of time, the route is supposed to return an accepted status code and send a email to the user when the processing is finished. The issue I am having is that the Task.Delay
is not being respected. Not matter how low I set PdfGenerationTimeLimitUntilEmail
the Wait.Any
still does not resolve until the createPdfTask
is finished. Interestingly enough when the generation throws an exception or completes, and the time has exceeded the Task.Delay
time, execution proceeds to return the Accepted Status. My suspicion is that the culprit is a DeadLock situation.
A related question which I have read thoroughly, but have not been able to apply to my problem: C#/.NET 4.5 - Why does "await Task.WhenAny" never return when provided with a Task.Delay in a WPF application's UI thread?
Is there anything obvious that I am missing? Or something about the thread context that I should know?
[HttpPost]
[Route("foo")]
public async Task<IHttpActionResult> Foo([FromBody] FooBody fooBody)
{
var routeUser = await ValidateUser();
async Task<Stream> CeatePdfFile()
{
var pdf = await createPdfFromFooData(fooBody);
return await pdfFileToStream(pdf);
}
var delay = Task.Delay(PdfGenerationTimeLimitUntilEmail);
var createPdfTask = CeatePdfFile();
var firstTaskResolved = await Task.WhenAny(createPdfTask , delay);
if (firstTaskResolved == createPdfTask)
{
var pdfFileStream = await createPdfTask ;
return new FileActionResult(pdfFileStream);
}
// Creating the PDF can take a long time, so just send an email when it's done
async void SendEmail(CancellationToken token)
{
var pdfFileStreamToEmail = await createPdfTask ;
_emailSender.SendDownloadEmail(routeUser.Email, pdfFileStreanToEmail);
}
HostingEnvironment.QueueBackgroundWorkItem(token => SendEmail(token));
return StatusCode(HttpStatusCode.Accepted);
}