So I'm trying to use task progress notification using IProgress<T>
. Here is what I do:
- Create a
Progress<T>
and attach a handler to itsProgressChanged
event. - In the event handler, I update UI-specific property to show progress.
- Run a loop and create
Task
objects to do units of work. Each Task usesProgress
object to report progress (which will in turn invokeProgressChanged
and update UI). - Use
Task.WaitAll()
to block till all tasks have finished. Show a completion message at the end.
The code looks something like this:
IProgress<Tuple<DataRow, MyVM>> BakeProgress;
BakeProgress = new Progress<Tuple<DataRow, MyVM>>();
((Progress<Tuple<DataRow, MyVM>>)BakeProgress).ProgressChanged += (sender, args) =>
{
_BakeProgress += 100.0 / AllDataRows.Length;
RaisePropertyChanged(NameOf(BakeProgress));
};
var BakeTasks = new List<Task>();
foreach (var dr in AllDataRows) {
BakeTasks.Add(Task.Run(() =>
{
var Baked = MyBakingFunc();
BakeProgress.Report(new Tuple<DataRow, MyVM>(dr, Baked));
return Baked;
}));
}
Task.WaitAll(BakeTasks.ToArray()); //Shouldn't this wait
MessageBox.Show("Baking Completed");
To my surprise, this code hits MessageBox
line before hitting ProgressChanged
event handler even once. What am I doing wrong?
N.B. It DOES hit ProgressChanged
event handler once for every Task instance, but only after hitting the Completed line.
N.B. Ah and I did read this, but since this is WPF, we do have a synchronization context in which the Progress
object was created.