End*_*Doe 5 .net c# task async-await
在我的服务器上,我有一条为用户生成pdf的路由.当生成时间超过指定的时间量时,该路由应返回已接受的状态代码,并在处理完成时向用户发送电子邮件.我遇到的问题Task.Delay是没有得到尊重.无论我设置多低PdfGenerationTimeLimitUntilEmail,Wait.Any仍然无法解决,直到createPdfTask完成.有趣的是,当生成抛出异常或完成,并且时间已经超过Task.Delay时间时,执行继续返回"已接受状态".我怀疑罪魁祸首是死锁情况.
一个相关的问题,我已经彻底阅读,但无法应用于我的问题: C#/.NET 4.5 - 为什么"等待Task.WhenAny"在WPF应用程序的UI线程中提供Task.Delay时永远不会返回?
我有什么遗漏吗?或者我应该知道的线程上下文?
[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);
}
Run Code Online (Sandbox Code Playgroud)
如果 Kevin Gosse 是正确的,那么这里真正的问题是,因此createPdfFromFooData在第一个之前做CeatePdfFile了很多工作:您可以添加 a来人为地强制额外等待,实质上将其余工作推送到相关上下文的工作队列上(或者线程池,否则):awaitTask.Yield()
async Task<Stream> CeatePdfFile()
{
await Task.Yield(); // force asynchronicity
var pdf = await createPdfFromFooData(fooBody);
return await pdfFileToStream(pdf);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
87 次 |
| 最近记录: |