I trying to use TPL on WinForms .NET 4.0, I followed this steps (go to the end of article) that are for WPF and made some small changes so it could work on WinForms but it still doesn't work.. It should display result on label and richTextBox but it not... I think the parallel process work cause mouse start moving slow for a while when I click the button..
public static double SumRootN(int root)
{ double result = 0;
for (int i = 1; i < 10000000; i++)
{ result += Math.Exp(Math.Log(i) / root);}
return result;
}
private void button1_Click(object sender, EventArgs e)
{ richTextBox1.Text = "";
label1.Text = "Milliseconds: ";
var watch = Stopwatch.StartNew();
List<Task> tasks = new List<Task>();
for (int i = 2; i < 20; i++)
{ int j = i;
var t = Task.Factory.StartNew
( () =>
{ var result = SumRootN(j);
Dispatcher.CurrentDispatcher.BeginInvoke
(new Action
( () => richTextBox1.Text += "root " + j.ToString()
+ " " + result.ToString() + Environment.NewLine
)
, null
);
}
);
tasks.Add(t);
}
Task.Factory.ContinueWhenAll
( tasks.ToArray()
, result =>
{ var time = watch.ElapsedMilliseconds;
Dispatcher.CurrentDispatcher.BeginInvoke
( new Action
( () =>
label1.Text += time.ToString()
)
);
}
);
}
As described in the link below, the correct way would be to eliminate the use of Dispatcher class altogether.Instead, you should create a relevant instance of TaskScheduler and pass it to the Task methods. http://blogs.msdn.com/b/csharpfaq/archive/2010/06/18/parallel-programming-task-schedulers-and-synchronization-context.aspx
That is
would become
Your code will not work because the thread UI to display result totally different with WPF. With WPF the thread UI is Dispatcher but on Windows Form is another one.
I have modified your code to help it work.
Leaving aside the whether it was good to do this way, from the learning angle and mentioned in comments topic "System.Windows.Threading.Dispatcher and WinForms?" with somewhat confusing answer:
it is pertinent to mention that (also provided my answer to mentioned above question):
Task.Factory.StartNew()
spawns executions on multiple threads different from the main UI or its child threadsSystem.Windows.Threading.Dispatcher DispatcherObject.Dispatcher
of UI thread absent in Winfows formsDispatcher.CurrentDispatcher
is getting the dispatchers on spawned by tasks non-ui threadsAnyway, from the didactic point of view of making minimum changes to the original WPF code, you should have caught and used UI dispatcher: