{"id":55996,"date":"2012-08-15T16:00:26","date_gmt":"2012-08-15T16:00:26","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/pfxteam\/2012\/08\/15\/implementing-then-with-await\/"},"modified":"2012-08-15T16:00:26","modified_gmt":"2012-08-15T16:00:26","slug":"implementing-then-with-await","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/implementing-then-with-await\/","title":{"rendered":"Implementing Then with Await"},"content":{"rendered":"<p>In a post a while ago, I talked about <a href=\"https:\/\/blogs.msdn.com\/b\/pfxteam\/archive\/2010\/11\/21\/10094564.aspx\">sequential composition of asynchronous operations<\/a>.&nbsp; Now that we have the async\/await keywords in C# and Visual Basic, such composition is trivial, and async\/await are indeed the recommended way to achieve such composition with these languages.<\/p>\n<p>However, in that post I also described a few &ldquo;Then&rdquo; methods (similar methods are now available in <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/apps\/br229728.aspx\">JavaScript<\/a> and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/hh750044.aspx\">VC++<\/a>), and I thought it&rsquo;d be fun to quickly show how Then can be implemented in terms of await. We&rsquo;d probably want to support Then methods that operate on either Task or Task&lt;TResult&gt;, and then run a continuation delegate that returns either void or TNewResult.&nbsp; This leads to four overloads, each of which can be implemented with just one or two lines of code:<\/p>\n<blockquote>\n<p><font face=\"Consolas\">public static async Task Then(       <br>&nbsp;&nbsp;&nbsp; this Task antecedent, Action continuation)        <br>{        <br>&nbsp;&nbsp;&nbsp; await antecedent;        <br>&nbsp;&nbsp;&nbsp; continuation();        <br>}        <\/p>\n<p>public static async Task&lt;TNewResult&gt; Then&lt;TNewResult&gt;(        <br>&nbsp;&nbsp;&nbsp; this Task antecedent, Func&lt;TNewResult&gt; continuation)        <br>{        <br>&nbsp;&nbsp;&nbsp; await antecedent;        <br>&nbsp;&nbsp;&nbsp; return continuation();        <br>}        <\/p>\n<p>public static async Task Then&lt;TResult&gt;(        <br>&nbsp;&nbsp;&nbsp; this Task&lt;TResult&gt; antecedent, Action&lt;TResult&gt; continuation)        <br>{        <br>&nbsp;&nbsp;&nbsp; continuation(await antecedent);        <br>}        <\/p>\n<p>public static async Task&lt;TNewResult&gt; Then&lt;TResult,TNewResult&gt;(        <br>&nbsp;&nbsp;&nbsp; this Task&lt;TResult&gt; antecedent, Func&lt;TResult,TNewResult&gt; continuation)        <br>{        <br>&nbsp;&nbsp;&nbsp; return continuation(await antecedent);        <br>}<\/font><\/p>\n<\/blockquote>\n<p>Simple, right?&nbsp; In each case, we just await the supplied task and then run the supplied continuation delegate (potentially passing in the result of the antecedent task).&nbsp; Exception handling is all handled correctly here as well, which is extra exciting since we didn&rsquo;t have to do anything special with regards to exceptions: any exceptions from either a non-successful antecedent task or from invoking the continuation delegate are automatically stored into the task returned from Then.<\/p>\n<p>There are a few additional overloads we might also want.&nbsp; These previous overloads work with continuation functions that return void or TNewResult, rather than Task or Task&lt;TNewResult&gt;.&nbsp; If you want to use await within the continuation functions, or if you otherwise want to return a Task from the delegate, additional overloads could help to automatically <a href=\"https:\/\/blogs.msdn.com\/b\/pfxteam\/archive\/2011\/10\/24\/10229468.aspx\">unwrap the task<\/a>.&nbsp; As before, these Then overloads are simple to write, with just a few tweaks from the previously shown overloads:<\/p>\n<blockquote>\n<p><font face=\"Consolas\">public static async Task Then(       <br>&nbsp;&nbsp;&nbsp; this Task task, Func&lt;Task&gt; continuation)        <br>{        <br>&nbsp;&nbsp;&nbsp; await task;        <br>&nbsp;&nbsp;&nbsp; <strong>await<\/strong> continuation();        <br>}        <\/p>\n<p>public static async Task&lt;TNewResult&gt; Then&lt;TNewResult&gt;(        <br>&nbsp;&nbsp;&nbsp; this Task task, Func&lt;Task&lt;TNewResult&gt;&gt; continuation)        <br>{        <br>&nbsp;&nbsp;&nbsp; await task;        <br>&nbsp;&nbsp;&nbsp; return <strong>await<\/strong> continuation();        <br>}        <\/p>\n<p>public static async Task Then&lt;TResult&gt;(        <br>&nbsp;&nbsp;&nbsp; this Task&lt;TResult&gt; task, Func&lt;TResult,Task&gt; continuation)        <br>{        <br>&nbsp;&nbsp;&nbsp; <strong>await<\/strong> continuation(await task);        <br>}        <\/p>\n<p>public static async Task&lt;TNewResult&gt; Then&lt;TResult, TNewResult&gt;(        <br>&nbsp;&nbsp;&nbsp; this Task&lt;TResult&gt; task, Func&lt;TResult, Task&lt;TNewResult&gt;&gt; continuation)        <br>{        <br>&nbsp;&nbsp;&nbsp; return <strong>await<\/strong> continuation(await task);        <br>}<\/font><\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>In a post a while ago, I talked about sequential composition of asynchronous operations.&nbsp; Now that we have the async\/await keywords in C# and Visual Basic, such composition is trivial, and async\/await are indeed the recommended way to achieve such composition with these languages. However, in that post I also described a few &ldquo;Then&rdquo; methods [&hellip;]<\/p>\n","protected":false},"author":360,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[7908],"tags":[7925,36,7911,7909,7912],"class_list":["post-55996","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pfxteam","tag-net-4-5","tag-async","tag-code-samples","tag-parallel-extensions","tag-task-parallel-library"],"acf":[],"blog_post_summary":"<p>In a post a while ago, I talked about sequential composition of asynchronous operations.&nbsp; Now that we have the async\/await keywords in C# and Visual Basic, such composition is trivial, and async\/await are indeed the recommended way to achieve such composition with these languages. However, in that post I also described a few &ldquo;Then&rdquo; methods [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/55996","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\/360"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=55996"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/55996\/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=55996"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=55996"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=55996"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}