簡體   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