<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Parallel.Invoke() vs. Explicit Task Management</title><link>http://blogs.msdn.com/pfxteam/archive/2009/07/10/9828076.aspx</link><description>Parallel Extensions offers a large variety of APIs supporting parallelism. During this blog the discussion will be focused on the methodology for making a choice between two of the new Parallel Extensions concepts: parallelism achieved by using Parallel.Invoke()</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: Parallel.Invoke() vs. Explicit Task Management</title><link>http://blogs.msdn.com/pfxteam/archive/2009/07/10/9828076.aspx#9829028</link><pubDate>Fri, 10 Jul 2009 22:57:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9829028</guid><dc:creator>Yuri</dc:creator><description>&lt;p&gt;Can you also explain the difference in how the parallel tasks may be canceled? For example, in hello world example, how would developer inform the Parallel.Invoke() that all pending tasks should be canceled, but those already executing should finish? What about the Task example?&lt;/p&gt;
&lt;p&gt;Thanks!&lt;/p&gt;
</description></item><item><title>re: Parallel.Invoke() vs. Explicit Task Management</title><link>http://blogs.msdn.com/pfxteam/archive/2009/07/10/9828076.aspx#9833795</link><pubDate>Wed, 15 Jul 2009 06:26:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9833795</guid><dc:creator>cristina manu</dc:creator><description>&lt;p&gt;[added several corrections for Beta1]&lt;/p&gt;
&lt;p&gt;Hello Yuri,&lt;/p&gt;
&lt;p&gt;Cancellation of Parallel Loops is supported through the concepts of CancellationTokenSource and CancellationToken. A cancellationToken can be passed to a ParallelFor through ParallelOptions.&lt;/p&gt;
&lt;p&gt;In order to cancel a task (or more), Cancel method can be used on a task.&lt;/p&gt;
&lt;p&gt;More info on cancellation please see at: &lt;a rel="nofollow" target="_new" href="http://blogs.msdn.com/pfxteam/archive/2009/06/22/9791840.aspx"&gt;http://blogs.msdn.com/pfxteam/archive/2009/06/22/9791840.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For your specific question I added below some source code with comments that, I hope will help. &lt;/p&gt;
&lt;p&gt;It addresses both questions: cancel a ParalleInvoke and cancel bunch of tasks.&lt;/p&gt;
&lt;p&gt;Thanks, &lt;/p&gt;
&lt;p&gt;Cristina&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; static CountdownEvent _ctd ;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; public static void ParallelInvokeSample()&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int n = System.Environment.ProcessorCount;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _ctd = new CountdownEvent(System.Environment.ProcessorCount);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //create an array of n + 1 actions&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Action[] allActions = CreateActions(n + 10);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CancellationTokenSource cts = new CancellationTokenSource();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ParallelOptions pOptions = new ParallelOptions() { CancellationToken = cts.Token };&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //on a different thread cancel the token by calling cancel on the tokenSource&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Thread cancel = new Thread(() =&amp;gt;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //wait for the parallel invocation to start&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _ctd.Wait();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cts.Cancel();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cancel.Start();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; try&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //pass the token to ParallelInvoke through parallelOptions&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Parallel.Invoke(pOptions, allActions);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; catch( Exception e )&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Console.WriteLine(e.Message);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cancel.Join();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; public static void TasksSample()&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p&gt;int n = System.Environment.ProcessorCount;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;_ctd = new CountdownEvent(System.Environment.ProcessorCount);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;try&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//first create a factory with RespectParentCancellation option&lt;/p&gt;
&lt;p&gt; TaskFactory factory = new TaskFactory(TaskCreationOptions.RespectParentCancellation,TaskContinuationOptions.None);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//create a number of tasks that will be cancelled through a common parent&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Task[] allTasks = new Task[n + 10];&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Task parent = Task.Factory.StartNew(() =&amp;gt;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for (int m = 0; m &amp;lt; n + 10; m++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;allTasks[m] = factory.StartNew(() =&amp;gt;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Console.WriteLine(&amp;quot;hello&amp;quot;);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;try { _ctd.Signal(); }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;catch&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//ignore any exception&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//do some long running work&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for (int k = 0; k &amp;lt; 1000; k++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Thread.Sleep(2);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;});&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;});&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//wait for some tasks to start&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;_ctd.Wait();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//cancell all the tasks, by cancelling the parent &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;parent.Cancel();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//wait on the tasks&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Task.WaitAll(allTasks);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;catch (AggregateException e)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Console.WriteLine(e.InnerExceptions.Select((x) =&amp;gt; x.Message).Aggregate((x, y) =&amp;gt; { return x + y; }));&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; static Action[] CreateActions(int n)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Action[] result = new Action[n];&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (int i = 0; i &amp;lt; n; i++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result[i] = () =&amp;gt; &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Console.WriteLine(&amp;quot;hello&amp;quot;);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; try { _ctd.Signal(); }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; catch&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //ignore any exception&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //do some long running work&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (int k = 0; k &amp;lt; 1000; k++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Thread.Sleep(2);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; };&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return result;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
</description></item><item><title>re: Parallel.Invoke() vs. Explicit Task Management</title><link>http://blogs.msdn.com/pfxteam/archive/2009/07/10/9828076.aspx#9834584</link><pubDate>Wed, 15 Jul 2009 22:25:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9834584</guid><dc:creator>Sachin</dc:creator><description>&lt;p&gt;Couple of quick questions:&lt;/p&gt;
&lt;p&gt;a) What is the performance impact (if any) of not having a &amp;quot;flat&amp;quot; task hierarchy. For example, if thread A is the main thread, what if we have:&lt;/p&gt;
&lt;p&gt;A --&amp;gt; B, C and B --&amp;gt; D,E vs.&lt;/p&gt;
&lt;p&gt;A --&amp;gt; C, D, E, &lt;/p&gt;
&lt;p&gt;The latter obfuscates code more, but there are less tasks created. Is the &amp;quot;performance&amp;quot; significant, or is this taken care of &amp;quot;under the covers&amp;quot;&lt;/p&gt;
&lt;p&gt;b) For the Tree Traversal code, you could have just added the actions without checking whether the left or right tree was null and it would still be functionally correct. Is there a significant performance trade-off between more concise code and doing this check before scheduling tasks?&lt;/p&gt;
</description></item><item><title>re: Parallel.Invoke() vs. Explicit Task Management</title><link>http://blogs.msdn.com/pfxteam/archive/2009/07/10/9828076.aspx#9835117</link><pubDate>Thu, 16 Jul 2009 08:22:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9835117</guid><dc:creator>cristina manu</dc:creator><description>&lt;p&gt;Hello Sachin&lt;/p&gt;
&lt;p&gt;For question “b”, without the checking that you mention, we would pay the cost of creating/scheduling new tasks (this means possibly creating new threads) &amp;nbsp;without really needing them. So. I would say that. if possible to do some un-expensive validations, it is recommended to do them before creating new tasks.&lt;/p&gt;
&lt;p&gt;For question “a”, &amp;nbsp;if I understand correctly your scenario, the 3 tasks (C, D E ) need to be scheduled. They can be scheduled either directly ( a.2), or through the task B ( a.1). I do not see a reason for introducing task B, if it is not needed. As above, any new task created might lead to a new thread injection. Also, with a new task, probably it will be needed to wait on it ( implicitly or explicitly) - this will add a performance penalty as well. In conclusion, I would recommend to try to not create tasks as long as they are not needed. &amp;nbsp;Parallel.Invoke takes care of creating the right number of tasks for executing all the actions.&lt;/p&gt;
&lt;p&gt;Also, because you may be interested in profiling parallel applications, I think that &amp;nbsp;you will find useful the new parallel profiling tools that &amp;nbsp;will be shipped with Visual Studio 2010. (&lt;a rel="nofollow" target="_new" href="http://blogs.msdn.com/hshafi/archive/2009/05/18/visual-studio-2010-beta-1-parallel-performance-tools.aspx"&gt;http://blogs.msdn.com/hshafi/archive/2009/05/18/visual-studio-2010-beta-1-parallel-performance-tools.aspx&lt;/a&gt;,. &amp;nbsp;&lt;a rel="nofollow" target="_new" href="http://blogs.msdn.com/hshafi/archive/2009/06/02/vs2010-how-to-use-the-parallel-performance-analysis-tools.aspx"&gt;http://blogs.msdn.com/hshafi/archive/2009/06/02/vs2010-how-to-use-the-parallel-performance-analysis-tools.aspx&lt;/a&gt;)&lt;/p&gt;
</description></item><item><title>re: Parallel.Invoke() vs. Explicit Task Management</title><link>http://blogs.msdn.com/pfxteam/archive/2009/07/10/9828076.aspx#9856230</link><pubDate>Mon, 03 Aug 2009 16:37:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9856230</guid><dc:creator>Michal</dc:creator><description>&lt;p&gt;Please, can you explain how it is with exception handling for both priciples. Imagine situation when the method TreeTraversal() fire exception. I expect, that some exception will be thrown from 'Task.WaitAll(tasks.ToArray())' or 'Parallel.Invoke(actions.ToArray())'. But the question is which expection wins when variable 'tasks' or 'actions' contains more than one task. Or all exceptions thrown in TreeTraversal() will be silently 'consumed' by framework?&lt;/p&gt;
&lt;p&gt;For tasks I know that I can review task.Exception property to see if this task raises any exception, but which exception will be thrown from Task.WaitAll? And how it is for Parallel.Invoke?&lt;/p&gt;
&lt;p&gt;Thanks Michal&lt;/p&gt;
</description></item><item><title>re: Parallel.Invoke() vs. Explicit Task Management</title><link>http://blogs.msdn.com/pfxteam/archive/2009/07/10/9828076.aspx#9856318</link><pubDate>Mon, 03 Aug 2009 18:43:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9856318</guid><dc:creator>toub</dc:creator><description>&lt;p&gt;Hi Michal-&lt;/p&gt;
&lt;p&gt;A general principle followed by the parallelism technologies in .NET 4 is that we never want to lose or eat exceptions. As such, a new exception type System.AggregateException has been introduced in .NET 4, which is an Exception-derived type that supports containing multiple inner exceptions rather than just a single inner exception. &amp;nbsp;In the cases you ask about, if any of the tasks passed to Task.WaitAll complete in a faulted state, all of their exceptions will be wrapped in an AggregateException instance, and that aggregate exception will be thrown, thus allowing you to see all of the exceptions. &amp;nbsp;Same goes for Parallel.Invoke: if multiple actions failed, Invoke will throw an aggregate containing all of the exceptions.&lt;/p&gt;
&lt;p&gt;More information on this is available in a new article just posted in the latest issue of MSDN Magazine: &lt;a rel="nofollow" target="_new" href="http://msdn.microsoft.com/en-us/magazine/ee321571.aspx"&gt;http://msdn.microsoft.com/en-us/magazine/ee321571.aspx&lt;/a&gt;.&lt;/p&gt;
</description></item></channel></rss>