我通过web api 1.0响应HTTP POST的异步操作。收到此请求后,我需要做两件事:
在一个完美的世界中,我会将数据放在某个队列中,并有一个小工作人员来处理队列。由于我无法立即执行此操作,因此在不影响用户的情况下确保完成此项工作的最佳方法是什么。
[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;
}
一个问题是您的Web API是否应该执行除此之外的任何操作
id
回复表示已收到请求。它在某种程度上取决于您期望或可能看到的负载类型。但是,如果您从一开始就关注可用线程的数量,那么答案可能就是您的Web API除了上述步骤之外什么都不做。
队列可以是文字队列,如MSMQ(或现在流行的任何东西。)或者它可以包含插入表中的记录。然后,单独的Windows服务可以处理该队列并执行I / O繁重的工作。它甚至不必在同一台服务器上。您可以单独缩放它。
如果用户确实想要一些最终指示,那么他们可以使用您返回的id
定期轮询它。但对我来说,关键是在这个声明中:
使用该标识完成I / O繁重的大量工作,WebApp和用户不会立即关注。
Web应用程序的工作是提供响应 - IOW,以执行用户关心的操作。如果它是长时间运行的,用户不关心I / O繁重的工作,那么我会考虑卸载它。