我对在ASP中使用异步操作有一些担忧。净MVC。什么时候它能提高应用程序的性能,什么时候不能?

在ASP中处处使用异步操作好吗?净MVC吗? 关于可等待方法:当我想查询数据库(通过EF/NHibernate/其他ORM)时,我应该使用async/await关键字吗? 在一个操作方法中,我可以使用await关键字异步查询数据库多少次?


当前回答

我的经验是,今天很多开发人员使用async/await作为控制器的默认设置。

我的建议是,只有在你知道它对你有帮助的时候才使用它。

原因是,正如Stephen Cleary和其他人已经提到的,它会引入性能问题,而不是解决问题,并且它只会在特定的场景中帮助您:

高流量控制器 可伸缩的后端

其他回答

我的5美分:

当且仅当你做IO操作时使用async/await,比如DB或外部服务webservice。 总是选择异步调用而不是DB。 每次查询DB时。

附注:第一点有例外情况,但你需要很好地理解异步内部。

作为一个额外的优势,如果需要,你可以并行执行很少的IO调用:

Task task1 = FooAsync(); // launch it, but don't wait for result
Task task2 = BarAsync(); // launch bar; now both foo and bar are running
await Task.WhenAll(task1, task2); // this is better in regard to exception handling
// use task1.Result, task2.Result

你可能会发现我在MSDN上关于这个主题的文章很有帮助;在那篇文章中,我花了很多篇幅描述什么时候应该在ASP上使用异步。NET,而不仅仅是如何在ASP.NET上使用async。

我对在ASP中使用异步操作有一些担忧。净MVC。什么时候它能提高我的应用程序的性能,什么时候呢?

首先,要理解async/await是关于释放线程的。在GUI应用程序上,它主要是关于释放GUI线程,以便更好的用户体验。在服务器应用程序(包括ASP。NET MVC),它主要是关于释放请求线程,以便服务器可以扩展。

特别是,它不会:

让您的个人请求更快地完成。事实上,他们会完成(只是一点点)慢一点。 当您按下等待按钮时,返回到调用者/浏览器。只等待ASP的“屈服”。NET线程池,不给浏览器。

第一个问题是——在ASP中处处使用异步操作好吗?净MVC吗?

我想说,在I/O的任何地方都使用它是很好的。不过,这未必是有益的(见下文)。

但是,将它用于cpu绑定的方法是不好的。有时候开发者认为他们可以通过调用Task来获得异步的好处。在他们的控制器中运行,这是一个可怕的想法。因为这段代码最终会占用另一个线程来释放请求线程,所以根本没有任何好处(事实上,它们正在承担额外线程切换的代价)!

当我想查询数据库(通过EF/NHibernate/其他ORM)时,我应该使用async/await关键字吗?

您可以使用任何可用的可等待方法。现在大多数主流游戏都支持异步,但也有少数不支持。如果你的ORM不支持异步,那么不要尝试将它包装在Task中。运行或类似的操作(参见上面)。

Note that I said "you could use". If you're talking about ASP.NET MVC with a single database backend, then you're (almost certainly) not going to get any scalability benefit from async. This is because IIS can handle far more concurrent requests than a single instance of SQL server (or other classic RDBMS). However, if your backend is more modern - a SQL server cluster, Azure SQL, NoSQL, etc - and your backend can scale, and your scalability bottleneck is IIS, then you can get a scalability benefit from async.

第三个问题-多少次我可以使用等待关键字查询数据库异步在一个单一的行动方法?

你想要多少都可以。但是,请注意,许多orm具有每个连接一个操作的规则。特别地,EF只允许每个DbContext执行单个操作;无论操作是同步的还是异步的,都是如此。

另外,请再次记住后端的可伸缩性。如果您正在使用单个SQLServer实例,并且您的IIS已经能够保持SQLServer的最大容量,那么对SQLServer施加两倍或三倍的压力根本不会对您有任何帮助。

As you know, MVC supports asynchronous controllers and you should take advantage of it. In case your Controller, performs a lengthy operation, (it might be a disk based I/o or a network call to another remote service), if the request is handled in synchronous manner, the IIS thread is busy the whole time. As a result, the thread is just waiting for the lengthy operation to complete. It can be better utilized by serving other requests while the operation requested in first is under progress. This will help in serving more concurrent requests. Your webservice will be highly scalable and will not easily run into C10k problem. It is a good idea to use async/await for db queries. and yes you can use them as many number of times as you deem fit.

看看这里的优秀建议。

async actions help best when the actions does some I\O operations to DB or some network bound calls where the thread that processes the request will be stalled before it gets answer from the DB or network bound call which you just invoked. It's best you use await with them and it will really improve the responsiveness of your application (because less ASP input\output threads will be stalled while waiting for the DB or any other operation like that). In all my applications whenever many calls to DB very necessary I've always wrapped them in awaiatable method and called that with await keyword.

我的经验是,今天很多开发人员使用async/await作为控制器的默认设置。

我的建议是,只有在你知道它对你有帮助的时候才使用它。

原因是,正如Stephen Cleary和其他人已经提到的,它会引入性能问题,而不是解决问题,并且它只会在特定的场景中帮助您:

高流量控制器 可伸缩的后端