Asp.Net WebApi run MongoDB query/save async

本文关键字:save async query MongoDB Net WebApi run Asp | 更新日期: 2023-09-27 17:52:50

我目前试图找出何时使用任务。

在我的项目中,我使用WebApi结合MongoDB来存储帐户信息。

所以对于下面的示例代码,我是否会更好地使用提交或SumbitAsync方法从客户端调用?

public class TestController : ApiController
{
    [HttpPost]
    public void Submit()
    {
        DoSave();
    }
    public async Task SubmitAsync()
    {
        await Task.Run(() => DoSave());
    }
    private void DoSave()
    {
        myMongoDbCollection.Save(new TestEntity());
    }
}

MongoDB c#驱动程序目前不支持async方法

Asp.Net WebApi run MongoDB query/save async

在这里使用Task.Run是没有意义的。

在ASP中使用异步I/O的意义. NET将释放您的线程,以便它可以处理其他请求,直到I/O完成。同时,没有线程将被阻塞。当I/O操作完成后,一个I/O完成端口将被发出信号,你的方法将继续执行。

使用Task.Run,您只是将此延迟到ThreadPool线程,并使线程阻塞等待I/o。

换句话说,如果客户端不支持异步I/O,其中一个线程将总是阻塞。因此,您不妨同步执行所有操作,以避免不必要的上下文切换。

摘自Stephen Cleary的博客文章&;Task。运行礼仪示例:不要使用Task。在实现中运行";

一旦你在Task中使用await,就会(至少)出现四个效率问题。在ASP中运行。净:

  • 额外的(不必要的)线程切换到任务。运行线程池线程。类似地,当该线程完成请求时,它必须进入请求上下文(这不是一个实际的线程切换,但确实有开销)。

  • 创建了额外的(不必要的)垃圾。异步编程是一种权衡:您以更高的内存使用为代价获得更高的响应性。在这种情况下,您最终会为异步操作创建更多完全不必要的垃圾。

  • ASP。. NET线程池启发式由Task抛弃。运行"unexpectedly"借用线程池线程。我在这方面没有太多经验,但我的直觉告诉我,如果意外任务真的很短,启发式应该恢复得很好,如果意外任务持续时间超过两秒钟,启发式就不会那么优雅地处理它了。

  • ASP。NET不能提前终止请求,即,如果客户端断开连接或请求超时。在同步的情况下,ASP。. NET知道请求线程,可以中止它。在异步情况下,ASP。. NET不知道辅助线程池线程是"for";该请求。可以通过使用取消令牌来解决这个问题,但这超出了本文的范围。