{"id":96655,"date":"2017-07-20T07:00:00","date_gmt":"2017-07-20T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=96655"},"modified":"2019-03-13T01:14:19","modified_gmt":"2019-03-13T08:14:19","slug":"20170720-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170720-00\/?p=96655","title":{"rendered":"Crash course in async and await"},"content":{"rendered":"<p>I&#8217;m going to assume that you know how the <code>async<\/code> and <code>await<\/code> keywords work. If you need a refresher, you can <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/ericlippert\/tag\/async\/\">read Eric Lippert&#8217;s extensive exposition of the subject<\/a>. Here&#8217;s the short version. <b>People who know how <code>async<\/code> and <code>await<\/code> work can go take a nap.<\/b> <\/p>\n<p>When you write a function that is marked <code>async<\/code>, then the function is broken up into a series of mini-functions at each <code>await<\/code> call. The code executes synchronously up until the first <code>await<\/code>, at which point the rest of the code is scheduled for resumption when the awaited thing produces a result. Optionally, a task is returned so that the caller can schedule its own continuation when the async function executes its <code>return<\/code> statement. <\/p>\n<p>For example, let&#8217;s take this function: <\/p>\n<pre>\nasync Task&lt;int&gt; GetTotalAsync()\n{\n  int total = GetStartValue();\n  int increment = await GetIncrementAsync();\n  return total + increment;\n}\n<\/pre>\n<p>This is shorthand for the following, with error checking has been elided for expository simplicity. <\/p>\n<pre>\nTask&lt;int&gt; GetTotalAsync()\n{\n  int total = GetStartValue();\n  return GetIncrementAsync().ContinueWith((incrementTask) =&gt; {\n    int increment = incrementTask.Result;\n    return total + increment;\n  });\n}\n<\/pre>\n<p>(Actually, that&#8217;s not really what happens; <a HREF=\"https:\/\/msdn.microsoft.com\/en-us\/magazine\/hh456403.aspx\">here are the gory details<\/a>.) <\/p>\n<p>The point is that the function executes normally until it encounters the first <code>await<\/code>, at which point it schedules itself as a continuation of the thing being awaited, and returns a new task that represents the continuation. When the thing being awaited completes, execution resumes with the continuation. That continuation might do some work, and then perform another <code>await<\/code>, which once again schedules itself as a continuation of the thing being awaited. Eventually, the original function runs to completion, at which point the chain of tasks terminates with a result, namely the thing that the original function returned. <\/p>\n<p>Note that when dealing with <code>async<\/code> functions, you have to distinguish with what the function <i>returns<\/i> and what it <i>produces<\/i> as a <i>result<\/i> when it <i>completes<\/i>. The <i>return value<\/i> is the thing that is returned synchronously by the function, typically a task of some sort. When execution reaches the end of the task chain, the task is said to have <i>completed<\/i>. The thing that comes out the end is called the <i>result<\/i>. <\/p>\n<p>In other words, there are two ways to call an <code>async<\/code> function. <\/p>\n<pre>\nvar task = SomethingAsync();\nvar result = await SomethingAsync();\n<\/pre>\n<p>If you call it without <code>await<\/code> then you get the raw task back. If you call it with <code>await<\/code>, then when the task completes, you get the result. <\/p>\n<p><b>People who know how <code>async<\/code> and <code>await<\/code> work can start waking up now.<\/b> You still know the stuff coming up next, but at least you&#8217;ll be primed for the discussion to come after. <\/p>\n<p>There are three ways of writing an <code>async<\/code> function: <\/p>\n<ul>\n<li><code>async Task&lt;T&gt; SomethingAsync() { ... return t; }<\/code> \n<li><code>async Task SomethingAsync() { ... }<\/code> \n<li><code>async void SomethingAsync() { ... }<\/code> <\/ul>\n<p>In all the cases, the function is transformed into a chain of tasks. The difference is what the function returns. <\/p>\n<p>In the first case, the function returns a task that eventually produces the <code>t<\/code>. <\/p>\n<p>In the second case, the function returns a task which has no product, but you can still <code>await<\/code> on it to know when it has run to completion. <\/p>\n<p>The third case is the nasty one. The third case is like the second case, except that <i>you don&#8217;t even get the task back<\/i>. You have no way of knowing when the function&#8217;s task has completed. <\/p>\n<p>The <code>async void<\/code> case is a &#8220;fire and forget&#8221;: You start the task chain, but you don&#8217;t care about when it&#8217;s finished. When the function returns, all you know is that everything up to the first <code>await<\/code> has executed. Everything after the first <code>await<\/code> will run at some unspecified point in the future that you have no access to. <\/p>\n<p>Now that I&#8217;ve set up the story, we&#8217;ll dig into the consequences next time. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hang on a second, I&#8217;ll get back to you.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-96655","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Hang on a second, I&#8217;ll get back to you.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96655","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=96655"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96655\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=96655"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=96655"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=96655"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}