Reputation: 34297
I've recently changed some code to be asynchronous, using the async/await pattern.
This code is now creating an exception:
private async void Refresh(object stateInfo)
{
await Task.Factory.StartNew(HydrateServerPingDtoList);
// more code here
}
private void HydrateServerPingDtoList()
{
// more code here.
// Exception occurs on this line:
this._serverPingDtoList.Add(new ServerPingDto() { ApplicationServer = server });
}
The exception:
This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
_serverPingDtoList
is the backing field for a WPF-bound property. Since I thought that async-await preserved the synchronization context, why would I get this error?
Upvotes: 2
Views: 1811
Reputation: 456322
await
restores the SynchronizationContext
within its own async
method. It will not propagate it to a background thread that you start via StartNew
.
On a side note, StartNew
should not be used in async
code; I explain why in detail on my blog. You should use Task.Run
to execute CPU-bound code.
However, any UI updates (including updates of data-bound properties) should be done on the UI thread, not on a background task. So, assuming that your HydrateServerPingDtoList
is actually CPU-bound, you can do this:
private ServerPingDto HydrateServerPingDtoList()
{
// more code here.
return new ServerPingDto() { ApplicationServer = server };
}
private async Task Refresh(object stateInfo)
{
var serverPingDto = await Task.Run(() => HydrateServerPingDtoList());
this._serverPingDtoList.Add(serverPingDto);
// more code here
}
Upvotes: 11