为所有服务器端代码调用 ConfigureAwait 的最佳实践 [英] Best practice to call ConfigureAwait for all server-side code

查看:32
本文介绍了为所有服务器端代码调用 ConfigureAwait 的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当你有服务器端代码(即一些 ApiController)并且你的函数是异步的 - 所以它们返回 Task - 是否被认为是最佳实践等待调用 ConfigureAwait(false) 的函数的时间?

When you have server-side code (i.e. some ApiController) and your functions are asynchronous - so they return Task<SomeObject> - is it considered best practice that any time you await functions that you call ConfigureAwait(false)?

我读到它的性能更高,因为它不必将线程上下文切换回原始线程上下文.但是,对于 ASP.NET Web Api,如果您的请求来自一个线程,并且您等待某个函数并调用 ConfigureAwait(false) 这可能会在您返回时将您置于不同的线程ApiController 函数的最终结果.

I had read that it is more performant since it doesn't have to switch thread contexts back to the original thread context. However, with ASP.NET Web Api, if your request is coming in on one thread, and you await some function and call ConfigureAwait(false) that could potentially put you on a different thread when you are returning the final result of your ApiController function.

我已经输入了我在下面谈论的示例:

I've typed up an example of what I am talking about below:

public class CustomerController : ApiController
{
    public async Task<Customer> Get(int id)
    {
        // you are on a particular thread here
        var customer = await GetCustomerAsync(id).ConfigureAwait(false);
        
        // now you are on a different thread!  will that cause problems?
        return customer;
    }
}

推荐答案

更新: ASP.NET Core 没有 SynchronizationContext.如果您使用的是 ASP.NET Core,则是否使用 ConfigureAwait(false) 都没有关系.

对于 ASP.NET完整"或经典"或其他任何内容,此答案的其余部分仍然适用.

For ASP.NET "Full" or "Classic" or whatever, the rest of this answer still applies.

原帖(针对非核心 ASP.NET):

ASP.NET 团队的这个视频有最好的信息在 ASP.NET 上使用 async.

我读到它的性能更高,因为它不必将线程上下文切换回原始线程上下文.

I had read that it is more performant since it doesn't have to switch thread contexts back to the original thread context.

对于 UI 应用程序来说也是如此,其中只有一个 UI 线程需要同步"回.

This is true with UI applications, where there is only one UI thread that you have to "sync" back to.

在 ASP.NET 中,情况有点复杂.当 async 方法恢复执行时,它会从 ASP.NET 线程池中获取一个线程.如果您使用 ConfigureAwait(false) 禁用上下文捕获,则线程将继续直接执行该方法.如果不禁用上下文捕获,那么线程会重新进入请求上下文,然后继续执行该方法.

In ASP.NET, the situation is a bit more complex. When an async method resumes execution, it grabs a thread from the ASP.NET thread pool. If you disable the context capture using ConfigureAwait(false), then the thread just continues executing the method directly. If you do not disable the context capture, then the thread will re-enter the request context and then continue to execute the method.

所以 ConfigureAwait(false) 不会为您节省 ASP.NET 中的线程跳转;它确实为您节省了重新输入请求上下文的时间,但这通常非常快.ConfigureAwait(false) 可能如果您尝试对请求进行少量并行处理,则可能很有用,但实际上 TPL 更适合大多数这些场景.

So ConfigureAwait(false) does not save you a thread jump in ASP.NET; it does save you the re-entering of the request context, but this is normally very fast. ConfigureAwait(false) could be useful if you're trying to do a small amount of parallel processing of a request, but really TPL is a better fit for most of those scenarios.

但是,对于 ASP.NET Web Api,如果您的请求来自一个线程,并且您等待某个函数并调用 ConfigureAwait(false),这可能会在您返回最终结果时将您置于不同的线程你的 ApiController 函数.

However, with ASP.NET Web Api, if your request is coming in on one thread, and you await some function and call ConfigureAwait(false) that could potentially put you on a different thread when you are returning the final result of your ApiController function.

实际上,只需执行 await 就可以做到这一点.一旦您的 async 方法命中 await方法 就会被阻塞,但 线程 会返回线程池.当方法准备好继续时,任何线程从线程池中被抢走并用于恢复方法.

Actually, just doing an await can do that. Once your async method hits an await, the method is blocked but the thread returns to the thread pool. When the method is ready to continue, any thread is snatched from the thread pool and used to resume the method.

ConfigureAwait 在 ASP.NET 中的唯一区别是该线程在恢复方法时是否进入请求上下文.

The only difference ConfigureAwait makes in ASP.NET is whether that thread enters the request context when resuming the method.

我在 MSDN 上关于 SynchronizationContext 和我的 async 介绍博文.

I have more background information in my MSDN article on SynchronizationContext and my async intro blog post.

这篇关于为所有服务器端代码调用 ConfigureAwait 的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆