【问题标题】:Not awaiting a task in a web api request不等待 Web api 请求中的任务
【发布时间】:2017-12-27 13:31:27
【问题描述】:

我继承了一些用 web api 编写的代码,我不确定我是否 100% 理解。它看起来像这样:

public async Task<IHttpActionResult> GetAll()
{
    var items = await repo.GetItems();

    Task.Run(async () =>
    {
        await MakeCallToExternalServiceAsync();

        await MakeCallToAnotherExternalServiceAsync();
    });

    return Ok(items);
}

在调用存储库以从数据存储中获取一些数据之后,代码会触发一个任务以对一些外部服务进行一些调用。假设这些调用都没有失败,还有其他问题吗?由于请求完成,这些调用会被中止吗?可能存在使用 Autofac 的“请求范围”的资源 - 这些资源会在请求完成后被释放吗?

【问题讨论】:

  • 是的,有一个问题:blog.stephencleary.com/2013/11/…
  • Task.Run 会导致比你想象的更多的问题,使用这个有一定的用例吗?
  • 是的,用例是像下面提到的斯蒂芬那样“解雇并忘记”。他还没有发现哪些其他问题?

标签: c# asp.net-web-api


【解决方案1】:

这是从 ASP.NET 请求中提前返回的“穷人”方式。又名“一劳永逸”。 There are much better solutions available.

假设这些调用都没有失败,还有其他问题吗?

好吧,如果他们中的任何一个确实失败了,你永远不会知道。

请求完成后,这些调用会被中止吗?

不一定。它们可能会运行到完成,也可能会被中止。 ASP.NET 不会仅仅因为请求完成就中止它们,但是 IIS 会在它决定回收 AppDomain / 进程时中止它们(它偶尔会这样做)。

可能存在使用 Autofac 的“请求范围”资源 - 请求完成后这些资源会被释放吗?

是的。请求完成后,使用任何请求范围的资源都不是一个好主意。

【讨论】:

  • 是的,我确信它已经完成,因为“让我们快速完成这项工作,并在以后找出更好的长期方法”。可惜后来没来。
  • Well, if any of them do fail, you would never know.我不完全同意这一点,您可以随时附加全局错误处理程序服务,请参阅此处stackoverflow.com/questions/16028919/…
  • @BRAHIMKamel:这不会捕获来自MakeCallToExternalServiceAsync 的异常。 “一劳永逸”的字面意思是“我不在乎这是否失败。”
猜你喜欢
  • 1970-01-01
  • 2016-05-27
  • 1970-01-01
  • 2019-11-07
  • 2015-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多