According to this
If the BackgroundWorker starts another BackgroundWorker from its DoWork handler, then the nested BackgroundWorker doesn’t capture the UI SynchronizationContext
However with .NET 4.0 and especially 4.5 onwards, I have seen a lot of sample codes like this one from here:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Shown += async ( s, e ) => { txtResult.Text = await DownloadAsync() + "Done!"; };
}
async Task<string> DownloadAsync()
{
using ( var wc = new WebClient() )
{
var progress = new Progress<DownloadStringTaskAsyncExProgress>();
progress.ProgressChanged += ( s, e ) =>
{
progressBar.Value = e.ProgressPercentage;
txtResult.Text += e.Text;
};
return await wc.DownloadStringTaskAsyncEx(
@"http://ancillaryasync.nickbutler.net/Murphy.ashx", progress );
}
}
}
So it looks like you can nest async call using tasks, and the SynchronizationContext will float down the nested calls. Is this correct?
If so, can someone explain to me how the TAP does this on a very high level.
If not what do I need to do make sure my nested call can post to the UI thread?
Or may be my understanding of the original article is completely wrong? Does creation of a new task picks up the current synchronization context by default? If so how can it ever run on anything other than the original synchronization context unless you explicitly give it a new synchronization context?
Please help me clear the confusion.
First off, the article you referenced is talking about
BackgroundWorker
and notasync
.BackgroundWorker
still works the same way in .NET 4.5, and still has the limitation around nested calls.For a description of how
async
works withSynchronizationContext
, you can look at the end of that article or read my intro onasync
. In short, when anawait
is encountered, by default it will capture the currentSynchronizationContext
(or if it'snull
, the currentTaskScheduler
), and use that to schedule the continuation.