簡體   English   中英

這是使用 ConfigureAwait(false) 的正確方法嗎?

[英]Is this the correct way to use ConfigureAwait(false)?

我正在構建一個 WPF 應用程序並調用這個自定義事件。 這里的問題是我應該在任何地方都調用ConfigureAwait(false)嗎? 正如你現在看到的,我調用了 2 次。 甚至在同一行中使用雙ConfigureAwait(false)第二種方法甚至 3 次。

// First approach
void RaiseProcessEvent(object sender, EventArgs e)
{
    Task.Run(async () => await APIManager.GetInstance.ProcessMethod()).ConfigureAwait(false);
}

// Second approach
void RaiseProcessEvent(object sender, EventArgs e)
{
    Task.Run(async () => await APIManager.GetInstance.ProcessMethod().ConfigureAwait(false)).ConfigureAwait(false);
}

// This function is in a singleton class
public async Task ProcessMethod()
{
    var result = await GetInstance.GetFinalResultFromHttpClientAsync().ConfigureAwait(false);     
}

這里的問題是我應該在任何地方都調用 ConfigureAwait(false) 嗎?

一般來說, 如果該方法不需要在其調用上下文上恢復,則應使用ConfigureAwait(false) 是否使用ConfigureAwait(false)應該在每個方法的基礎上做出,並且應該用於該方法中的每個await ,或者不應該用於該方法中的每個await

更實用的是,應該在旨在重用的代碼中使用ConfigureAwait(false) ,可能在不同的上下文中。 應用程序代碼很少需要使用ConfigureAwait(false) ,盡管我遇到過需要防止一堆延續中斷 UI 線程的情況

正如你現在看到的,我打了 2 次電話。 甚至在同一行中使用 double configure(false) 的第二種方法進行 3 次。

在這些情況下, ConfigureAwait(false)毫無意義。 原因如下:

//first approach
Task.Run(async () => await APIManager.GetInstance.ProcessMethod()).ConfigureAwait(false);

ConfigureAwait配置一個await 它不配置任務。 由於從Task.Run返回的任務從不await ,因此此ConfigureAwait不執行任何操作。

//second approach
Task.Run(async () => await APIManager.GetInstance.ProcessMethod().ConfigureAwait(false)).ConfigureAwait(false);

ConfigureAwait(false)false部分用於continueOnCapturedContext參數。 所以ConfigureAwait(false)是說“這個方法不需要在捕獲的上下文上繼續”。 但是在這種情況下, async委托正在線程池上運行(這就是Task.Run所做的),因此您知道無論如何都沒有要捕獲的上下文。

旁注 1:使用Task.Run調用異步方法時,通常會省略asyncawait關鍵字 例如: Task.Run(() => APIManager.GetInstance.ProcessMethod()); . 因此, ConfigureAwait(false)問題無論如何都沒有實際意義,因為不再有await

旁注 2: Task.RunTask.Run返回的任務意味着代碼正在執行即發即忘,這幾乎總是一個可怕的錯誤。 除此之外,這意味着任何異常都會被默默地吞下。 使用await幾乎總是更好:

async void RaiseProcessEvent(object sender, EventArgs e)
{
  await Task.Run(() => APIManager.GetInstance.ProcessMethod());
}

現在有一個awaitTask.Run返回的任務,所以在這一點上提出這個問題是合適的:這個await應該使用ConfigureAwait(false)嗎? 這里的意見可能會有所不同,但我會說不,因為這顯然是應用程序級代碼(UI 事件處理程序),並且大多數開發人員會假設運行事件處理程序的代碼將在 UI 線程上(即使之前有一個await在那種方法中)。 因此,為了獲得最大的可維護性,我不會在 UI 事件處理程序方法中使用ConfigureAwait(false) ,除非我出於性能原因必須添加它。

歡迎來到 SO!

如果您正在編寫應用程序代碼,那么您可能根本不應該使用它。 MSDN 上的ConfigureAwait 常見問題解答中對此進行了大量討論。

特爾;博士:

如果您正在編寫通用庫/應用程序模型不可知的代碼,請使用 ConfigureAwait(false),否則不要使用。

也就是說,這是一個有點復雜的話題,所以我相信這里會有很多其他人不同意。 我已經編寫了一些極其復雜的多任務 WPF 應用程序,但我腦子里想不起來我實際上需要在應用程序代碼中使用它的任何情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM