- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在我的服务器上,我有一个为用户生成 pdf 的路由。当生成时间超过指定的时间量时,路由应该返回一个已接受的状态代码,并在处理完成后向用户发送一封电子邮件。我遇到的问题是 Task.Delay
没有得到尊重。无论我将 PdfGenerationTimeLimitUntilEmail
设置得有多低,Wait.Any
仍然不会解析,直到 createPdfTask
完成。有趣的是,当生成抛出异常或完成,并且时间超过 Task.Delay
时间时,执行继续返回已接受状态。我怀疑罪魁祸首是死锁情况。
一个相关的问题,我已经仔细阅读过,但无法应用于我的问题: C#/.NET 4.5 - Why does "await Task.WhenAny" never return when provided with a Task.Delay in a WPF application's UI thread?
有什么明显我遗漏的吗?或者我应该知道的有关线程上下文的信息?
[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);
}
最佳答案
如果 Kevin Gosse 是正确的,那么这里真正的问题是 createPdfFromFooData
因此 CeatePdfFile
在第一个 await
之前 正在做很多工作: 你可以添加 Task.Yield()
人为地强制执行额外的等待,本质上是将其余工作推到相关上下文(或线程池,否则)的工作队列中:
async Task<Stream> CeatePdfFile()
{
await Task.Yield(); // force asynchronicity
var pdf = await createPdfFromFooData(fooBody);
return await pdfFileToStream(pdf);
}
关于C# Async ApiController 路由问题解决 Task.WhenAny 与 Task.Delay,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54789596/
现有项目的 Controller 继承自: Controller:RouteTable.Routes.MapRoute with "{controller}/{action}/{id}"。 ApiCo
我正在计划一个“通用的”客户端-服务器架构。当前结构如下: 服务器 Asp.Net WebApp(托管在本地或以天蓝色) EntityFrameworkCore数据层 带有每个EF-Model Con
我的 ApiController 没有收到包装在 View 模型中的 DateTime 对象。 这是我的 Controller 的内容。 public class FlowApiController
我有一个 ApiController 并想用包括路由在内的单元测试来测试它。 一个例子: [RoutePrefix("prefix")] public class Controller : ApiCo
我已经使用 Azure 移动应用程序创建了后端服务。使用提供的 SDK,离线同步在移动客户端上运行良好。我使用的所有 Controller 都是 TableController。现在我想添加一个简单的
ApiController 是否有可用于初始化异步资源的扩展点/覆盖? 我想要这样的东西: public ValuesController : ApiController { private
使用 Visual Studio 2012.2,MVC4 网络应用程序。 我的 ApiController 有这样的请求: http://localhost/api/keys?ids[]=1&ids[
我正在使用 .NET Framework 4.0 和 C# 开发 ASP.NET Web Api 应用。 我有这个: using System; using System.Collections.Ge
我研究了如何在 MVC 项目中使用 API,但我对此有一些疑问。 (在有人问之前,我正在用 C# 语言编写)。 到目前为止,我知道 Api 的路由配置是在 WebApiConfig 类中设置的,默认路
如果我有一个只有简单属性(例如 Name 等)的 Customer 类,那么我可以创建一个派生的 CustomersController来自 ApiController,并使用 URL /api/cu
基于此视频 https://www.youtube.com/watch?v=IVvJX4CoLUY我添加了 using System.Web; using System.Web.Http; 但我仍然得
我正在 VS 2013 中处理现有的 Windows 服务项目。 我添加了一个 Web API Controller 类,我现在不记得它是 (v2.1) 还是 (v1) Controller 类...
正如标题所示,我想扩展 ApiContoller 类以包含一些自定义属性和辅助方法,但每当我尝试将它用于 Controller 时,我都会收到消息 Multiple actions were foun
我正在尝试测试我制作的 WebApi Controller 。我尝试使用依赖注入(inject)来简化测试。尽管它实际上有相反的效果。 我目前有一个 Controller 在其构造函数中采用 repo
我正在尝试创建一个用于登录的 Api Controller ,应该在使用我的 CustomerController (Api) 访问数据之前使用它。 问题是当我尝试访问 AccountControll
我做了一个简单的 GET,循环 10 次,每次迭代等待 1 秒来模拟工作。当我从 Chrome 中的一个选项卡调用此路由时,需要 10 秒(如预期)。当我同时调用此路由(从 2 个不同的选项卡)时,第
我想在我计划跨项目重用的类库中放置一个具有多个操作和子路由的 REST [ApiController]。我想通过端点路由注册 Controller 路由,并在每个项目的 appsettings.jso
我有一个 Apicontroller,它依赖于工作单元对象。如何编写模拟 ApiController 的测试用例,它依赖于 ApiController 构造函数中实现的工作单元。 代码如下: API
我目前正在从事一个项目,其中每个 API Controller 都需要记录事件。一个粗略的例子可能是: [Route(...)] public IHttpActionResult Foo(...) {
在我的 apicontroller 中,我使用 base.user 来标识要在查找中使用的经过身份验证的用户。现在我正在为此编写单元测试,但我不知道如何模拟 apicontroller.user。我需
我是一名优秀的程序员,十分优秀!