【发布时间】:2018-01-03 19:48:36
【问题描述】:
我有通过 web api 1.0 响应 HTTP POST 的异步操作。收到此请求后,我需要做两件事:
- 执行数据库插入并将新条目的标识返回给调用该函数的 WebApp。
- 使用该身份来完成大量 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