8

I have read that a 'BackgroundWorker' is designed to be replaced by Ansyc/Await.

Because I like the condensed look of Async/Await, I am starting to convert some of my BackgroundWorkers into Async/Await calls.

This is an example of the code I have (called from the UI):

public async void RunFromTheUI()
{
   await OtherAction();
}

public async void OtherAction()
{
   var results = await services.SomeRemoteAction();

   foreach (var result in results)
   {
      result.SemiIntenseCalculation(); 
      Several();
      Other();
      NonAsync();
      Calls();  
   }

   SomeFileIO();
}

When I call RunFromTheUI it will return almost immediately (as per the Async and Await design).

But when it resumes after services.SomeRemoteAction() finishes it has a foreach loop and another method call to run through.

My question is: If that loop is a performance hog will it freeze the UI? (Before I had it all in a Background worker thread, so it did not slow the UI down).

Note: I am targeting .Net 4.0 and using the Async Nuget Package.

Community
  • 1
  • 1
Vaccano
  • 78,325
  • 149
  • 468
  • 850
  • async/await and BackgroundWorker solve two different problems. BG worker is more precisely replaced by Tasks. Async only replaces these when the worker body code basically idles, where BGW/Tasks are still useful when you need to do heavy lifting. I looks like you're waiting on service results in your question, just FYI. – Factor Mystic Dec 18 '12 at 22:26
  • 1. Your code won't compile, you can't `await` an `async void` method. 2. You should avoid using `async void` methods, they cannot be `await`ed and make exception handling more difficult. – svick Dec 18 '12 at 23:09

1 Answers1

6

My question is: If that loop is a performance hog will it freeze the UI?

Yes, it will. The rest of the async method will still execute on the UI thread when the remote action has completed. If you don't want that to happen, then the options are:

  • Use ConfigureAwait(continueOnCapturedContext: false) so that the continuation doesn't execute on the UI thread
  • Execute the whole of the method in a different thread to start with, using Task.Run. (You could still make it an async method, to avoid blocking a thread when you didn't need to.)

Basically, if you've got a load of either synchronous, blocking calls or CPU-intensive work, you want to avoid that happening on the UI thread, which is the opposite of what async/await does for you by default.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    `Task.Run` has better defaults than `Task.Factory.StartNew` if you're using `async`. [Stephen Toub goes into details.](http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx) – Stephen Cleary Dec 18 '12 at 22:18
  • @StephenCleary: Fixed, thanks. I wasn't paying attention - `Task.StartNew` wasn't valid to start with, of course :) – Jon Skeet Dec 19 '12 at 04:25
  • Jon: Any good starting point to read/understand async/await, task? – shahkalpesh Jan 07 '13 at 06:15
  • @shahkalpesh: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx and http://msdn.microsoft.com/en-us/magazine/hh456401.aspx are good starting points. – Jon Skeet Jan 07 '13 at 06:46
  • I don't have Task.Run. Is that not available in the Async Pack for .NET 4.0 (in VS 2012)? – Vaccano Jan 08 '13 at 16:43