Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the differences between using ConfigureAwait(false) and Task.Run?

I understand that it's recommended to use ConfigureAwait(false) for awaits in library code so that subsequent code does not run in the caller's execution context, which could be a UI thread. I also understand that await Task.Run(CpuBoundWork) should be used instead of CpuBoundWork() for the same reason.

Example with ConfigureAwait

public async Task<HtmlDocument> LoadPage(Uri address) {     using (var client = new HttpClient())     using (var httpResponse = await client.GetAsync(address).ConfigureAwait(false))     using (var responseContent = httpResponse.Content)     using (var contentStream = await responseContent.ReadAsStreamAsync().ConfigureAwait(false))         return LoadHtmlDocument(contentStream); //CPU-bound } 

Example with Task.Run

public async Task<HtmlDocument> LoadPage(Uri address) {     using (var client = new HttpClient())     using (var httpResponse = await client.GetAsync(address))         return await Task.Run(async () =>         {             using (var responseContent = httpResponse.Content)             using (var contentStream = await responseContent.ReadAsStreamAsync())                 return LoadHtmlDocument(contentStream); //CPU-bound         }); } 

What are the differences between these two approaches?

like image 929
Sam Avatar asked Feb 16 '13 01:02

Sam


People also ask

When should you use ConfigureAwait false?

As a general rule, every piece of code that is not in a view model and/or that does not need to go back on the main thread should use ConfigureAwait false. This is simple, easy and can improve the performance of an application by freeing the UI thread for a little longer.

What is difference between ConfigureAwait true and false?

If we set 'ConfigureAwait(true)' then the continuation task runs on the same thread used before the 'await' statement. If we set 'ConfigureAwait(false)' then the continuation task runs on the available thread pool thread.

What is ConfigureAwait () used for?

ConfigureAwait in Action You capture the current context before awaiting the task, leaving it to the task context, then recovering (re-entering) it back when the task completes.

When should I use ConfigureAwait true?

In this video we answer the ever popular question “Which do I use, ConfigureAwait True or False?”. The direct answer to this question is: – If you are a writing code for the UI, use ConfigureAwait(true).


2 Answers

When you say Task.Run, you are saying that you have some CPU work to do that may take a long time, so it should always be run on a thread pool thread.

When you say ConfigureAwait(false), you are saying that the rest of that async method does not need the original context. ConfigureAwait is more of an optimization hint; it does not always mean that the continuation is run on a thread pool thread.

like image 195
Stephen Cleary Avatar answered Sep 20 '22 01:09

Stephen Cleary


In this case, your Task.Run version will have a bit more overhead, as the first await call (await client.GetAsync(address)) will still marshal back into the calling context, as will the results of the Task.Run call.

In the first example, on the other hand, your first Async() method is configured to not require marshaling back into the calling context, which allows the continuation to run on a background thread still. As such, there won't be any marshaling back into the caller's context.

like image 24
Reed Copsey Avatar answered Sep 18 '22 01:09

Reed Copsey