Assuming ChartViewModels
is an ObservableCollection<T>
, the following code works as expected:
await Dispatcher.InvokeAsync(() =>
{
ChartViewModels.Clear();
ChartViewModels.AddRange(initializedCharts);
}, DispatcherPriority.DataBind, mCancellationToken.Token);
await UpdateChartsWithValuesAsync(chartsToInitialize, ChartViewModels).ConfigureAwait(false);
Instead, if I wrap the the UpdateChartsWithValuesAsync
method call in the ContinueWith
delegate, the method is not awaited anymore. I already tried to change the ConfigureAwait(false)
to true
but nothing seems to change. Below the edited code:
await Dispatcher.InvokeAsync(() =>
{
ChartViewModels.Clear();
ChartViewModels.AddRange(initializedCharts);
}, DispatcherPriority.DataBind, mCancellationToken.Token).Task
.ContinueWith(async t => await UpdateChartsWithValuesAsync(chartsToInitialize, ChartViewModels).ConfigureAwait(false), mCancellationToken.Token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current).ConfigureAwait(false);
The code into the Dispatcher
is always executed before the ContinueWith
delegate, but it doesn't await UpdateChartsWithValuesAsync
to complete anymore, raising nasty bugs.
Can anyone explain this behaviour? Thanks
WPF, .NET Framework 4.7 project
Simply put, .ContinueWith()
does not do await
in its implementation, instead runs the passed in delegate as it is and returns a Task of Task (Task<Task>>
). This outer task, because not awaiting on the passed in delegate, completes immediately.
What I suggest, don't use .ContinueWith()
in this case, simply stick to await. If you really keen to keep the current code, you can do .ContinueWith().Unwrap()
, what will does the trick.
Also here is an another related question in the topic: Use an async callback with Task.ContinueWith
If you wanna learn more in depth, the source code of ContinueWith
: https://referencesource.microsoft.com/#mscorlib/system/threading/tasks/Task.cs,4532