{"id":2233,"date":"2009-04-06T16:23:00","date_gmt":"2009-04-06T16:23:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/pfxteam\/2009\/04\/06\/whats-new-in-beta-1-for-the-task-parallel-library-part-23\/"},"modified":"2009-04-06T16:23:00","modified_gmt":"2009-04-06T16:23:00","slug":"whats-new-in-beta-1-for-the-task-parallel-library-part-23","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/whats-new-in-beta-1-for-the-task-parallel-library-part-23\/","title":{"rendered":"What\u2019s new in Beta 1 for the Task Parallel Library? (Part 2\/3)"},"content":{"rendered":"<p>Related Posts:<\/p>\n<ul>\n<li><a title=\"What&rsquo;s new in Beta 1 for the Task Parallel Library? (Part 1\/3)\" href=\"https:\/\/blogs.msdn.com\/pfxteam\/archive\/2009\/03\/27\/9514938.aspx\" target=\"_blank\">What&rsquo;s new in Beta 1 for the Task Parallel Library? (Part 1\/3)<\/a><\/li>\n<li><a title=\"What's new in the Task Parallel Library for Beta 1 (Part 3\/3)?\" href=\"https:\/\/blogs.msdn.com\/pfxteam\/archive\/2009\/04\/14\/9549246.aspx\" target=\"_blank\">What&#8217;s new in Beta 1 for the Task Parallel Library? (Part 3\/3)<\/a><\/li>\n<\/ul>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">Last week we talked about changes under the covers, redesigns in System.Threading.Parallel, and using CancellationTokens.<span>&nbsp; <\/span>So what else is new in TPL for Beta 1?<span>&nbsp; <\/span>In this post, we&rsquo;ll cover the new <b>TaskFactory<\/b> class, the plight of Future&lt;T&gt; (<b>Task&lt;TResult&gt;<\/b>), and <b>TaskCompletionSource&lt;TResult&gt;<\/b>.<\/font><\/p>\n<h2><font color=\"#4f81bd\" size=\"4\" face=\"Cambria\">TaskFactory<\/font><\/h2>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">There are two ways to create and schedule Tasks: use constructors and instance methods, or use static methods like StartNew.<span>&nbsp; <\/span>In previous releases, these two functionalities were jammed into the Task class, and we realized that separating them would result in a cleaner design.<span>&nbsp; <\/span>So we introduced the TaskFactory class, which contains all static methods that create and\/or schedule Tasks.<span>&nbsp; <\/span>In Beta 1, these static methods include more than just StartNew, but those will be covered in the next post!<\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">For convenience, Task now contains a static Factory property which returns a default instance of TaskFactory.<span>&nbsp; <\/span>So for many users, the biggest practical difference is that where you would have used Task.StartNew (or Task.Create in the June 2008 CTP and earlier), you now use:<\/font><\/p>\n<p class=\"MsoNoSpacing\"><span>Task.Factory.StartNew(() =&gt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNoSpacing\"><span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNoSpacing\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>&#8230;<br>});<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNoSpacing\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">An additional advantage of TaskFactory is the ability to consolidate the specifying of options such as creation options, continuation options, and which scheduler to use:<\/font><\/p>\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><span>TaskFactory myFactory = <span>new<\/span> TaskFactory(<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>myScheduler, myCreationOptions, myContinuationOptions);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Task t0 = myFactory.StartNew(() =&gt; { });<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Task t1 = myFactory.StartNew(() =&gt; { });<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Task t2 = myFactory.StartNew(() =&gt; { });<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<h2><font color=\"#4f81bd\" size=\"4\" face=\"Cambria\">Task&lt;TResult&gt;<\/font><\/h2>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">In previous releases, Tasks that produced results were called Futures.<span>&nbsp; <\/span>Moving forward, we&rsquo;ve opted to rename Future&lt;T&gt; to Task&lt;TResult&gt;, a type that derives from Task.<span>&nbsp; <\/span>There were a number of reasons, including:<\/font><\/p>\n<p class=\"MsoListParagraphCxSpFirst\"><span><span><font size=\"3\">&middot;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\" face=\"Calibri\">We constantly found ourselves describing Futures as &ldquo;tasks that return results&rdquo;.<\/font><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span><font size=\"3\">&middot;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\" face=\"Calibri\">Many folks, that we spoke with, found the name Task&lt;TResult&gt; clearer.<\/font><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span><font size=\"3\">&middot;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\" face=\"Calibri\">There is some discrepancy in literature and concurrency circles about exactly what&rsquo;s implied by the term &ldquo;future&rdquo; (What functionality should or should not be exposed?<span>&nbsp; <\/span>Side-effect free?)<\/font><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span><font size=\"3\">&middot;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\" face=\"Calibri\">The name Future has a not-related-to-Task implication.<span>&nbsp; <\/span>However, we wanted Task&lt;TResult&gt; to derive from Task so that the former could be treated polymorphically as the latter. <\/font><\/p>\n<p class=\"MsoListParagraphCxSpLast\"><span><span><font size=\"3\">&middot;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\" face=\"Calibri\">We wanted TaskFactory methods to be able to return &ldquo;tasks that return results&rdquo;.<span>&nbsp; <\/span>For example, it would have been odd for Task.Factory.StartNew to return a Future.<\/font><\/p>\n<h2><font color=\"#4f81bd\" size=\"4\" face=\"Cambria\">TaskCompletionSource&lt;TResult&gt;<\/font><\/h2>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">A Task&lt;TResult&gt; is typically used to asynchronously execute a delegate that computes and returns a result.<span>&nbsp; <\/span>Sometimes however, the asynchronous operation cannot be represented by a delegate, but rather is performed by an external entity.<\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">Such functionality was originally supported on Future&lt;T&gt;, via a special constructor that did not take a delegate.<span>&nbsp; <\/span>A Future created this way could have its Value or Exception properties set using the respective setters.<span>&nbsp; <\/span>There were several problems with this approach, for example:<\/font><\/p>\n<p class=\"MsoListParagraphCxSpFirst\"><span><span><font size=\"3\">&middot;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\" face=\"Calibri\">The setters were only usable if the Future&lt;T&gt; was created with the special constructor.<\/font><\/p>\n<p class=\"MsoListParagraphCxSpLast\"><span><span><font size=\"3\">&middot;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\" face=\"Calibri\">Commonly, a producer would want to hand out a Future&lt;T&gt; to consumers, but not allow the consumers to resolve it.<span>&nbsp; <\/span>However, in this scheme, anyone who had a reference to the Future&lt;T&gt; could resolve it.<\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">We&rsquo;ve addressed these issues by introducing a new TaskCompletionSource&lt;TResult&gt; type:<\/font><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>TaskCompletionSource&lt;int&gt; tcs = new TaskCompletionSource&lt;int&gt;();<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Task&lt;int&gt; task = tcs.Task;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>\/\/ Sometime later&#8230;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>tcs.SetResult(computedResult);<span>&nbsp; <\/span>\/\/ Or tcs.SetException(exc), or tcs.SetCanceled()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>\/\/ In a consumer elsewhere&#8230;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>try { Console.WriteLine(task.Result); }<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNoSpacing\"><span>catch (AggregateException ae) { }<\/span><span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">In this post, we covered the most fundamental redesigns to TPL tasks.<span>&nbsp; <\/span>&ldquo;What&rsquo;s new in Beta 1 for TPL (Part 3\/3)&rdquo; will cover all remaining changes, such as other helper methods on TaskFactory and the new TaskScheduler.<span>&nbsp; <\/span>Look forward to it!<\/font><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Related Posts: What&rsquo;s new in Beta 1 for the Task Parallel Library? (Part 1\/3) What&#8217;s new in Beta 1 for the Task Parallel Library? (Part 3\/3) Last week we talked about changes under the covers, redesigns in System.Threading.Parallel, and using CancellationTokens.&nbsp; So what else is new in TPL for Beta 1?&nbsp; In this post, we&rsquo;ll [&hellip;]<\/p>\n","protected":false},"author":485,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[7908],"tags":[],"class_list":["post-2233","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pfxteam"],"acf":[],"blog_post_summary":"<p>Related Posts: What&rsquo;s new in Beta 1 for the Task Parallel Library? (Part 1\/3) What&#8217;s new in Beta 1 for the Task Parallel Library? (Part 3\/3) Last week we talked about changes under the covers, redesigns in System.Threading.Parallel, and using CancellationTokens.&nbsp; So what else is new in TPL for Beta 1?&nbsp; In this post, we&rsquo;ll [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/2233","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/485"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=2233"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/2233\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=2233"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=2233"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=2233"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}