The framework already provides the IProgress inteface for this purpose, and an implementation in Progress. To report progress, call IProgress.Report with a progressvalue. The value T can be any type, not just a number.
Each IProgress implementation can work in its own way. Progress raises an event and calls a callback you pass to it when you create it.
Additionally, Progress.Report executes asynchronously. Under the covers, it uses SychronizationContext.Post to execute its callback and all event handlers on the thread that created the Progress instance.
Assuming you create a progress value class like this:
class ProgressValue
{
public long Step{get;set;}
public string Message {get;set;}
}
You could write something like this:
IProgress<ProgressValue> myProgress=new Progress<ProgressValue>(p=>
{
myProgressBar.Value=p.Step;
});
IList<int> myVeryLargeList=...;
Parallel.ForEach(myVeryLargeList,item,state,step=>
{
//Do some heavy work
myProgress.Report(new ProgressValue
{
Step=step,
Message=String.Format("Processed step {0}",step);
});
});
EDIT
Oops! Progress implements IProgress explicitly. You have to cast it to IProgress , as @Tim noticed.
Fixed the code to explicitly declare myProgress as an IProgress.