views:

412

answers:

2

I know that Task Parallel Library is still in Beta and there are likely to be less resources available but from whatever I have read, library gives very special treatment to task scheduling, exception handling and cancellation.

But I don't find any references to progress reporting and sending incremental results from tasks. These 2 things seem too important to ignore. Can you throw some light on how to handle these in Task Parallel Library or refer some articles which explains them?

+5  A: 

This example updates a progress bar:

using System;   
using System.Threading;   
using System.Threading.Tasks;   
using System.Windows.Forms;   

class SimpleProgressBar : Form   
{   
 [STAThread]   
 static void Main(string[] args)   
 {   
  Application.EnableVisualStyles();   
  Application.Run(new SimpleProgressBar());   
 }   

 protected override void OnLoad(EventArgs e)   
 {   
  base.OnLoad(e);   

  int iterations = 100;   

  ProgressBar pb = new ProgressBar();   
  pb.Maximum = iterations;   
  pb.Dock = DockStyle.Fill;   
  Controls.Add(pb);   

  Task.Create(delegate   
  {   
   Parallel.For(0, iterations, i =>  
   {   
    Thread.SpinWait(50000000); // do work here   
    BeginInvoke((Action)delegate { pb.Value++; });   
   });   
  });   
 }   
}

http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/38d7a436-e1d1-4af8-8525-791ebeed9663

Robert Harvey
+3  A: 

There is no built-in support for this like what BackgroundWorker had.

You can use SynchronizationContext directly; there's an excellent video here: http://www.rocksolidknowledge.com/ScreenCasts.mvc/Watch?video=TasksAndThreadAffinity.wmv

The author develops two solutions in this video: one using SynchronizationContext and another using Task Continuations. For your problem, continuations will not work, but the SynchronizationContext approach would work fine.

P.S. If you're creating reusable code, then when you capture SynchronizationContext.Current, you should test for null and (if it is null) use a default-constructed SynchronizationContext instead.

UPDATE: I've posted code for this on my blog. My solution is actually based on a Task that is scheduled back to the UI thread by a TaskScheduler which uses SynchronizationContext underneath. Unlike the accepted answer, this solution will work for both WPF and Windows Forms.

Stephen Cleary