【问题标题】:Best Practice for I/O Heavy Async Task with WebApi使用 WebApi 处理 I/O 繁重异步任务的最佳实践
【发布时间】:2018-01-03 19:48:36
【问题描述】:

我有通过 web api 1.0 响应 HTTP POST 的异步操作。收到此请求后,我需要做两件事:

  1. 执行数据库插入并将新条目的标识返回给调用该函数的 WebApp。
  2. 使用该身份来完成大量 I/O 繁重的工作,WebApp 和用户不会立即关心这些工作。

在一个完美的世界中,我会将数据放在某个队列中,并让一个小工人来处理队列。由于我无法立即执行此操作,因此确保在不影响用户的情况下完成这项工作的最佳方法是什么。

[HttpPost]
public async Task<int> Post([FromBody]Object myObject)
{
    return await new ObjectLogic().InsertObject(myObject);
}
public async Task<int> InsertObject(Object myObject)
{
    var id = await new ObjectData().InsertObjectRoot(myObject);
    Task.Run(() =>  new ObjectData().ObjectWork(id, myObject));
    return id;
}

这是我提出的解决方案,但我认为必须有更好的解决方案,因为我基本上是从线程池中窃取线程,直到我的工作完成。有没有更好的办法?我想我可以在 InsertObject 方法中使用 ConfigureAwait(false),因为我真的不关心那里的上下文。

// await async function but use ConfigureAwait
public async Task<int> InsertObject(Object myObject)
{
    var id = await new ObjectData().InsertObjectRoot(myObject);
    await new ObjectData().ObjectWork(id, myObject).ConfigureAwait(false);
    return id;
}

【问题讨论】:

  • 您是否担心线程会用完?有可能……为什么你不能在单独的线程上实现你的队列想法?
  • 一个容易遵循的规则是 Task.Run 对于 IO 绑定工作来说总是一个坏主意。
  • 你应该在那里做一些分析。如果您遇到 IO 瓶颈,请不要担心异步。如果您遇到线程池瓶颈,请执行异步操作。
  • 其实你并没有窃取任何线程。 stackoverflow.com/questions/37419572/…
  • 有很多关于如何实现即发即弃的坏主意的帖子。确保搜索...

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


【解决方案1】:

一个问题是您的 Web API 是否应该做任何事情而不是

  • 接收请求
  • 将其放入队列中
  • 回复id 表示已收到请求。

这在某种程度上取决于您期望或可能看到的负载类型。但是,如果您从一开始就担心可用线程的数量,那么答案可能是您的 Web API 除了上述步骤之外什么都不做。

队列可以是文字队列,如 MSMQ(或现在流行的任何东西)。或者它可以包含插入到表中的记录。然后,一个单独的 Windows 服务可以处理该队列并执行 I/O 繁重的工作。它甚至不必在同一台服务器上。您可以单独缩放。

如果用户确实想要一些最终指示,那么他们可以使用您返回的id 定期轮询它。但对我来说,关键在于这句话:

使用该身份完成大量 I/O 繁重的工作,WebApp 和用户不会立即关心。

Web 应用程序的工作是提供响应 - IOW,执行用户所做 关心的事情。如果它是长时间运行的、用户不关心的 I/O 繁重工作,那么我会考虑卸载它。

【讨论】:

  • 首先,感谢您的回复。我相信你是正确的使用 MSMQ 或类似的东西是长期的解决方案。我正在寻找正确的直接步骤,因为我目前有现有的代码在生产中运行并且它可以工作。似乎“HostingEnvironment.QueueBackgroundWorkItem”可能是一个婴儿步骤,因为它注册了任务。
猜你喜欢
  • 1970-01-01
  • 2017-07-05
  • 2020-12-01
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 2019-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多