使用WebApi进行I / O重异步任务的最佳实践

问题描述 投票:-2回答:1

我通过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;
}
c# asp.net-web-api async-await
1个回答
2
投票

一个问题是您的Web API是否应该执行除此之外的任何操作

  • 收到请求
  • 把它放在队列上
  • id回复表示已收到请求。

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

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

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

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

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

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.