繁体   English   中英

“上下文”在C#async / await代码中的确切含义是什么?

[英]What does 'context' exactly mean in C# async/await code?

让我们看看一些简单的C#async / await代码,其中我await使用ConfigureAwait(false)进行await之前和之后有一个对象引用( objConfigureAwait(false)

private async Task<SomeObject> AnAsyncLibraryMethod(SomeObject obj)
{
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    obj.Name = "Harry"; // <-- obj here

    // MAIN POINT
    var newSubObj = await FetchOverHttpAsync().ConfigureAwait(false);

    // Continuation here
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    obj.Name = "Sally"; // <-- same obj here
    return obj;
}

public class SomeObject { public string Name; }

ConfigureAwait(false)似乎意味着不会 将延续编组回到捕获的原始上下文 - 好吧,但这究竟意味着什么? 我已经尝试了上面的代码并且obj IS被正确引用(即使它在不同的线程上恢复)。

所以“上下文”似乎不是线程的工作内存(即线程本地存储)。 那么“上下文”包含什么? 因此,它到底意味着什么

将继续编组回到捕获的原始上下文

正如我在async介绍博客文章中所描述的那样,“上下文”是:

  • SynchronizationContext.Current ,除非它为null ,在这种情况下它是
  • TaskScheduler.Current 请注意,如果没有当前任务调度程序,则TaskScheduler.CurrentTaskScheduler.Default相同,后者是一个线程池上下文。

绝大多数情况下,这是UI或ASP.NET请求上下文(两种类型的SynchronizationContext ),或者它是线程池上下文。 任务调度程序上下文很少发挥作用。

请注意,此上下文仅用于计划延续 它对编组没有任何作用; 在你的例子中,捕获obj就像从lambda表达式引用它一样。

如果我没错,那么ConfigureAwait(false); 只表示在等待代码之后运行的代码不需要在await之前使用SynchronizationContext

Stephen指出, SynchronizationContext可以是不同的东西。 因此,假设您处于Web环境中,并且await之后的代码依赖于HttpContext.Current.Items,如果您设置ConfigureAwait(false); ,这可能不再起作用ConfigureAwait(false);

例如,MVC控制器中的以下代码将引发异常

    public async Task<ActionResult> Index()
    {
        System.Web.HttpContext.Current.Items["test"] = "test";

        var result = await SomethingAsync();

        return View();
    }

    private async Task<object> SomethingAsync()
    {
        await Task.Delay(1000).ConfigureAwait(false);

        // this will throw a nullpointer if ConfigureAwait is set to false
        return System.Web.HttpContext.Current.Items["test"];
    }

你的变量只是在方法的范围内,因此它是可用的,基本上是方法闭包/范围,如果这是有意义的?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM