C# 使用WebApi执行I/O繁重异步任务的最佳实践
我有一个异步操作通过WebAPI 1.0响应HTTP POST。收到此请求时,我需要做两件事:C# 使用WebApi执行I/O繁重异步任务的最佳实践,c#,asp.net-web-api,async-await,C#,Asp.net Web Api,Async Await,我有一个异步操作通过WebAPI 1.0响应HTTP POST。收到此请求时,我需要做两件事: 执行数据库插入,并将该新条目的标识返回到调用该函数的WebApp 使用这个身份做一大堆I/O繁重的工作,这些工作是WebApp和用户不会立即关心的 在一个完美的世界里,我会把数据放在某个队列的某个地方,然后让一个小工人来处理队列。既然我不能立即这样做,那么什么是确保这项工作在不影响用户的情况下完成的最好方法呢 [HttpPost] public async Task<int> 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;
}
[HttpPost]
公共异步任务发布([FromBody]对象myObject)
{
返回wait wait new ObjectLogic().InsertObject(myObject);
}
公共异步任务插入对象(对象myObject)
{
var id=wait new ObjectData().InsertObjectRoot(myObject);
运行(()=>newObjectData().ObjectWork(id,myObject));
返回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;
}
//等待异步函数,但使用ConfigureAwait
公共异步任务插入对象(对象myObject)
{
var id=wait new ObjectData().InsertObjectRoot(myObject);
等待新的ObjectData().ObjectWork(id,myObject).ConfigureAwait(false);
返回id;
}
一个问题是,您的Web API是否应该除了
- 收到请求
- 把它放在队列上
- 使用
响应以指示已收到请求id
id
每隔一段时间进行轮询。但对我来说,关键在于这句话:
使用该身份进行大量I/O繁重的工作,这是Web应用程序和用户不会立即关心的。
web应用程序的工作是提供响应,即用户真正关心的事情。如果它是长时间运行的、用户不关心的I/O重工,那么我会考虑卸载它。你担心你的线程会用完吗?这是可能的。。。为什么你不能在一个单独的线程上实现你的队列想法呢?一个简单的规则就是这个任务。运行对于IO绑定的工作来说总是一个坏主意。你应该在那里做一些分析。如果遇到IO瓶颈,那么不要担心异步。如果您遇到了线程池瓶颈,那么就执行异步。实际上,您并没有窃取任何线程。有很多帖子都是关于如何实施用火遗忘的坏主意的。确保搜索…首先,感谢您的回复。我相信你是正确的使用MSMQ或类似的东西是长期的解决方案。我正在寻找一个婴儿步骤在正确的直接,因为我目前有现有的代码在生产中运行,它的工作。“HostingEnvironment.QueueBackgroundWorkItem”似乎是一个小步骤,因为它注册了任务。