I want to update a progress bar in winforms using delegate from task.
scheduler = TaskScheduler.FromCurrentSynchronizationContext();
public delegate void NotifyAboutIterationEnd(int iteration);
public event NotifyAboutIterationEnd Notify;
var task = Task.Factory.StartNew(() =>
{
//...
Task.Factory.StartNew(() =>
{
Notify(++index);
}, CancellationToken.None, TaskCreationOptions.None, scheduler);
//...
When I start this code, the last breakpoint I can hit is in line Notify(++index);
Then the program freezes and it’s over.
If I change the scheduler to e.g. scheduler = TaskScheduler.Current; then I have an exception that gui cannot be modified from other thread. That mean the delegate/event is working ok. So why doesn’t it work in the first situation?
This happens because Task.Factory.StartNew() actually doesn’t start a new task, but SCEDULE it. The default scheduller can start them even after your main task complete. Remember Task != Threads.
Thread.Start – allways starts thread immidiately, Task.Factory.StartNew or Task.Start only schedule. You can use .Wait() after your Task.Factory.StartNew(). This will cause waiting for progress bar is updated.
But, I am shure this is not best solution. Solution I really recommend if your calculations take a lot of time us Task.Factory.Startnew with TaskCreationOptions.LongRunning
and Notify.BeginInvoke for updating progressbar. Of cause handler of the notify event must be properly implemented according to Winforms Updating UI Asynchronously Pattern.
You can see an example at Winforms Updating UI Asynchronously Pattern – Need to Generalize
Hope this helps!
Good lack in parrallel ;).