Pourquoi aurais-je pris la peine d’utiliser Task.ConfigureAwait (continueOnCapturedContext: false);

Considérez le code suivant des formulaires Windows:

private async void UpdateUIControlClicked(object sender, EventArgs e) { this.txtUIControl.Text = "I will be updated after 2nd await - i hope!"; await Task.Delay(5000).ConfigureAwait(continueOnCapturedContext: false); this.txtUIControl.Text = "I am updated now."; } 

Ici, l’exception est lancée à la 3ème ligne car après l’attente, le code est exécuté sur le thread non-interface utilisateur. Où ConfigureAwait (false) est utile?

Stephen Cleary a une très bonne série à ce sujet, que vous pouvez trouver ici . J’ai cité l’article spécifique à votre question:

La plupart du temps, vous n’avez pas besoin de synchroniser avec le contexte «principal». La plupart des méthodes asynchrones seront conçues en fonction de la composition: elles attendent d’autres opérations et chacune représente une opération asynchrone elle-même (qui peut être composée par d’autres). Dans ce cas, vous voulez dire au serveur de ne pas capturer le contexte actuel en appelant ConfigureAwait et en transmettant false , par exemple:

 private async Task DownloadFileAsync(ssortingng fileName) { // Use HttpClient or whatever to download the file contents. var fileContents = await DownloadFileContentsAsync(fileName).ConfigureAwait(false); // Note that because of the ConfigureAwait(false), we are not on the original context here. // Instead, we're running on the thread pool. // Write the file contents out to a disk file. await WriteToDiskAsync(fileName, fileContents).ConfigureAwait(false); // The second call to ConfigureAwait(false) is not *required*, but it is Good Practice. } // WinForms example (it works exactly the same for WPF). private async void DownloadFileButton_Click(object sender, EventArgs e) { // Since we asynchronously wait, the UI thread is not blocked by the file download. await DownloadFileAsync(fileNameTextBox.Text); // Since we resume on the UI context, we can directly access UI elements. resultTextBox.Text = "File downloaded!"; } 

La chose importante à noter avec cet exemple est que chaque «niveau» des appels de méthode asynchrone a son propre contexte. DownloadFileButton_Click démarré dans le contexte de l’interface utilisateur et appelé DownloadFileAsync . DownloadFileAsync également démarré dans le contexte de l’interface utilisateur, mais a ensuite quitté son contexte en appelant ConfigureAwait(false) . Le rest de DownloadFileAsync s’exécute dans le contexte du pool de threads. Cependant, lorsque DownloadFileAsync termine et que DownloadFileButton _Click est réactivé, il reprend dans le contexte de l’interface utilisateur.

Une bonne règle à suivre est d’utiliser ConfigureAwait(false) sauf si vous savez que vous avez besoin du contexte.