2013-09-23 410 views
4

的意外行爲如果您執行在ASP.NET MVC下面的代碼,你可以在調試窗口,它將正確恢復線程的文化await後,即使ManagedThreadId變化看:異步/等待:ConfigureAwait

public async Task<ActionResult> Index() 
{ 
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE"); 

    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId); 
    Debug.WriteLine(Thread.CurrentThread.CurrentUICulture); 

    await SomeMethod(); 

    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId); 
    Debug.WriteLine(Thread.CurrentThread.CurrentUICulture); 

    return View(); 
} 

private async Task SomeMethod() 
{ 
    await Task.Delay(100).ConfigureAwait(false); 
} 

然後我剛從的someMethod()以索引()移動ConfigureAwait(假的),除了這一點,這是與上面相同的代碼:

public async Task<ActionResult> Index() 
{ 
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE"); 

    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId); 
    Debug.WriteLine(Thread.CurrentThread.CurrentUICulture); 

    await SomeMethod().ConfigureAwait(false); 

    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId); 
    Debug.WriteLine(Thread.CurrentThread.CurrentUICulture); 

    return View(); 
} 

private async Task SomeMethod() 
{ 
    await Task.Delay(100); 
} 

現在不恢復我的文化卻始終將其設置爲new CultureInfo("en-US")。但我期望使用這兩種方法,結果必須相同。現在還不清楚,爲什麼會這樣。

+0

'ConfigureAwait(true)'做了什麼? 'bool'參數控制是否「封送原始上下文」 - 是不是你想要的? –

+0

我預計如果將'ConfigureAwait(false)'添加到'await',它會影響整個異步調用鏈,而不僅僅是當前的方法,因爲否則使用它的性能好處很小。 – user1224129

回答

5

如果您使用await task.ConfigureAwait(false),那麼該方法的其餘部分(以及從那裏調用的任何內容)將不會在原始上下文中執行。但是這不會影響邏輯調用樹中更高的任何代碼。

我認爲這是實現它的唯一合乎邏輯的方法。如果上面的代碼必須在原始上下文中執行(這很常見),那麼ConfigureAwait()庫代碼內部的某處應該不會影響它。

要根據你使這更具體的,使用的WinForms await是行不通的下面這個簡單的例子,如果ConfigureAwait()表現:

async void ButtonClicked(object sender, EventArgs e) 
{ 
    textBlock.Text = "Downloading"; 
    await DownloadAsync(); 
    textBlock.Text = "Finished"; 
} 

async Task DownloadAsync() 
{ 
    data = await new HttpClient().GetStringAsync(url).ConfigureAwait(false); 
} 
1

您可以創建自己的awaiter,以與await文化流繼續回調,即使它發生在不同的池線程上。所以,您的通話將類似於:

await SomeMethod().WithCulture(); 

斯蒂芬Toub顯示究竟是如何做到這一點的PFX Team blog,尋找CultureAwaiter

0

(來自手機)

你不僅失去了線程文化。你正在失去整個背景。

當存在SynchronizationContext時,將繼續發送到該SynchronizationContext。在ASP.NET中,這是一個請求處理程序線程,在UI線程的客戶端UI中。

ConfigureAwait(false)指示生成的狀態機不會發布到捕獲的(如果有的話)SynchronizationContext。

索引不應該使用它,但應從那裏調用任何代碼。