当我不能使用 ConfigureAwait(false) 时?

When I cannot use ConfigureAwait(false)?

根据最佳实践,如果可以,建议将 .ConfigureAwait(false)async/await 关键字结合使用:

await Task.Run(RunSomethingAsync).ConfigureAwait(false);

能否请您举例说明我无法使用.ConfigureAwait(false)的情况?

"cannot" 使用 ConfigureAwait(false) 当你真正关心你所在的同步上下文时。例如,假设 GUI申请:

public async void SomeButtonClick(object sender, EventArgs e)
{
    var result = await SomeAsyncOperation().ConfigureAwait(false);
    textBox.Text = result;
}

当您从 ConfigureAwait return 时,您将不会回到 UI 线程。这将导致 InvalidOperationException.

来自source: Asynchronous .NET Client Libraries for Your HTTP API and Awareness of async/await's Bad Effects

When you are awaiting on a method with await keyword, compiler generates bunch of code in behalf of you. One of the purposes of this action is to handle synchronization with the UI (or main) thread. The key component of this feature is the SynchronizationContext.Current which gets the synchronization context for the current thread. SynchronizationContext.Current is populated depending on the environment you are in. The GetAwaiter method of Task looks up for SynchronizationContext.Current. If current synchronization context is not null, the continuation that gets passed to that awaiter will get posted back to that synchronization context.

When consuming a method, which uses the new asynchronous language features, in a blocking fashion, you will end up with a deadlock if you have an available SynchronizationContext. When you are consuming such methods in a blocking fashion (waiting on the Task with Wait method or taking the result directly from the Result property of the Task), you will block the main thread at the same time. When eventually the Task completes inside that method in the threadpool, it is going to invoke the continuation to post back to the main thread because SynchronizationContext.Current is available and captured. But there is a problem here: the UI thread is blocked and you have a deadlock!