{"id":2391,"date":"2014-03-10T13:00:13","date_gmt":"2014-03-10T13:00:13","guid":{"rendered":"http:\/\/writeasync.net\/?p=2391"},"modified":"2014-03-09T11:03:35","modified_gmt":"2014-03-09T11:03:35","slug":"just-cant-await-in-4-0","status":"publish","type":"post","link":"http:\/\/writeasync.net\/?p=2391","title":{"rendered":"Just can&#8217;t [a]wait (in 4.0)"},"content":{"rendered":"<p>Writing managed asynchronous code has been <em>possible<\/em> since the advent of <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.iasyncresult(v=vs.71).aspx\"><code>IAsyncResult<\/code><\/a> in <a href=\"http:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=96\">.NET 1.0<\/a>. However, it has not been <em>easy<\/em> until <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/hh191443.aspx\"><code>async<\/code>\/<code>await<\/code> in .NET 4.5<\/a>. Unfortunately, there are situations where you really <em>need to<\/em> implement asynchrony but are stuck with an older framework version. If you are on .NET 4.0 and want an easy way to use <code>Task<\/code>-based async, then read on!<\/p>\n<p>First, let&#8217;s talk about <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dscyy5s0.aspx\">iterator blocks<\/a>. <a href=\"http:\/\/ericlippert.com\">Eric Lippert<\/a> once referred to them as a &#8220;<a href=\"http:\/\/blogs.msdn.com\/b\/ericlippert\/archive\/2009\/07\/09\/iterator-blocks-part-one.aspx\">weak kind of coroutine<\/a>.&#8221; Indeed, an iterator might more accurately be referred to as a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Generator_(computer_science)\">generator<\/a>, a special kind of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Coroutine\">coroutine<\/a>. As you are probably aware, an iterator block allows you to generate a sequence of values one item at a time by <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/9k7k7cf0.aspx\"><code>yield<\/code><\/a>ing them to the caller:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\/\/ Infinite loop??\r\nprivate static IEnumerable&lt;string&gt; Letters()\r\n{\r\n    int i = 0;\r\n    while (true)\r\n    {\r\n        char letter = (char)('A' + i);\r\n        yield return letter.ToString();\r\n        if (++i == 26)\r\n        {\r\n            i = 0;\r\n        }\r\n    }\r\n}\r\n\r\n\/\/ Here we Take() only the first three, i.e. allow\r\n\/\/ the method to yield 3 times only and then move on.\r\nprivate static void PrintThreeLetters()\r\n{\r\n    foreach (string letter in Letters().Take(3))\r\n    {\r\n        Console.Write(letter);\r\n    }\r\n\r\n    Console.WriteLine();\r\n}\r\n<\/pre>\n<p>How does it do this? Ultimately, the compiler generates a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Finite-state_machine\">state machine<\/a> class to hold the captured state (e.g. local variables in your method), keep track of the next step to execute, and so on. (<a href=\"http:\/\/msmvps.com\/blogs\/jon_skeet\/\">Jon Skeet<\/a> goes over some of the gory details in his <a href=\"http:\/\/manning.com\/skeet3\/\">C# in Depth<\/a> article &#8220;<a href=\"http:\/\/csharpindepth.com\/Articles\/Chapter6\/IteratorBlockImplementation.aspx\">Iterator block implementation details<\/a>.&#8221;)<\/p>\n<p>What does this have to with async? Quite a bit, actually! The use of iterators for asynchrony has a long history, going back at least as far as <a href=\"http:\/\/www.wintellect.com\/blogs\/jeffreyr\">Jeffrey Richter<\/a>&#8216;s <a href=\"http:\/\/msdn.microsoft.com\/en-us\/magazine\/cc546608.aspx\"><code>AsyncEnumerator<\/code><\/a>. <a href=\"http:\/\/blogs.msdn.com\/b\/toub\/\">Stephen Toub<\/a> wrote about the possibilities of using <a href=\"http:\/\/blogs.msdn.com\/b\/pfxteam\/archive\/2009\/06\/30\/9809774.aspx\">iterators and Tasks together<\/a> when .NET 4.5 was just a twinkle in <a href=\"http:\/\/en.wikipedia.org\/wiki\/Anders_Hejlsberg\">Anders Hejlsberg<\/a>&#8216;s eye.<\/p>\n<p>So just how can we use an iterator to simplify async? The basic idea is that we yield a result for every async step we need to invoke. A main loop on the outside keeps advancing the enumerator and executing these async calls. If the call completes immediately (i.e. synchronously), it handles the result and continues. If not, it schedules a continuation so that on completion, the iterator state machine will help us resume where we left off.<\/p>\n<p>Complicated? Perhaps a little, for the implementer (me). But the job is made somewhat easier with the help of TDD and unit tests showing that all the behavior is designed and implemented correctly. And the end result makes for a much improved async experience for .NET 4.0 users.<\/p>\n<p>So, without further ado, allow me to introduce <code>AsyncOperation<\/code>, the iterator-based solution to Task-based async in .NET 4.0. The code is available in my <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/tree\/master\/projects\/AsyncEnumSample\">AsyncEnumSample project on GitHub<\/a>. The <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commits\/master\/projects\/AsyncEnumSample\">commit history<\/a> shows how the code evolved via unit tests. I should note that this is one of the more complicated projects I have done for this blog with <strong>more than 35 unit tests<\/strong>, many of which initially passed without any code changes. This is because I wanted to be confident all behaviors were covered in case of later refactoring.<\/p>\n<p>Here is the basic API surface area of <code>AsyncOperation<\/code>:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nnamespace AsyncEnumSample\r\n{\r\n    public abstract class AsyncOperation&lt;TResult&gt;\r\n    {\r\n        protected AsyncOperation();\r\n\r\n        protected interface IExceptionHandler\r\n        {\r\n            bool Handle(Exception exception);\r\n        }\r\n\r\n        protected TResult Result { get; set; }\r\n\r\n        public Task&lt;TResult&gt; Start();\r\n\r\n        protected abstract IEnumerator&lt;Step&gt; Steps();\r\n\r\n        protected struct Step\r\n        {\r\n            public static Task&lt;T&gt; TaskFromResult&lt;T&gt;(T result);\r\n\r\n            public static Task TaskFromException(Exception exception);\r\n\r\n            public static Task&lt;T&gt; TaskFromException&lt;T&gt;(Exception exception);\r\n\r\n            public static Step Await&lt;TState&gt;(TState state, Func&lt;TState, AsyncCallback, object, IAsyncResult&gt; begin, Action&lt;TState, IAsyncResult&gt; end, params IExceptionHandler&#x5B;] handlers);\r\n\r\n            public static Step Await&lt;TState&gt;(TState state, Func&lt;TState, Task&gt; doAsync, params IExceptionHandler&#x5B;] handlers);\r\n\r\n            public static Step Await&lt;TState, TCallResult&gt;(TState state, Func&lt;TState, Task&lt;TCallResult&gt;&gt; doAsync, Action&lt;TState, TCallResult&gt; afterCall, params IExceptionHandler&#x5B;] handlers);\r\n\r\n            public void Invoke();\r\n        }\r\n\r\n        protected static class Catch&lt;TException&gt; where TException : Exception\r\n        {\r\n            public static IExceptionHandler AndHandle&lt;TState&gt;(TState state, Func&lt;TState, TException, bool&gt; handler);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>The <code>Start<\/code> method drives the iterator loop which is implemented by a derived class via the <code>Steps<\/code> method. Of particular importance is the <code>Step<\/code> struct, which provides various <code>Await<\/code> factory methods for different kinds of async steps. Three basic patterns are supported: old-style <code>BeginXxx<\/code>\/<code>EndXxx<\/code>, <code>Task<\/code> (no result), and <code>Task&lt;T&gt;<\/code> (with result). (Note that a <code>TState<\/code> object is expected to be provided to each delegate, to improve performance and prevent implicit capture of locals if desired.)<\/p>\n<p>Sample usage for each type of call:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\/\/ Begin\/End (assigning result to a member variable)\r\nyield return Step.Await(\r\n    this,\r\n    (thisPtr, c, s) =&gt; thisPtr.someObj.BeginOp(c, s),\r\n    (thisPtr, r) =&gt; thisPtr.retValue = thisPtr.someObj.EndOp(r));\r\n\r\n\/\/ Task (no result)\r\nyield return Step.Await(\r\n    this,\r\n    thisPtr =&gt; thisPtr.someObj.DoAsync());\r\n\r\n\/\/ Task&lt;T&gt; (with result, assigning to member variable after completion)\r\nyield return Step.Await(\r\n    this,\r\n    thisPtr =&gt; thisPtr.someObj.DoWithResultAsync(),\r\n    (thisPtr, r) =&gt; thisPtr.retValue = r);\r\n<\/pre>\n<p>Note that you <strong>must <code>yield return<\/code> every <code>Step<\/code><\/strong>. It is unfortunately easy to forget this, which is one drawback of trying to build advanced patterns without real compiler support. Another limitation is that you can&#8217;t easily write catch blocks, however there is a relatively simple way around this using the provided <code>Catch&lt;TException&gt;.AndHandle<\/code> functionality. An example:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nprotected override IEnumerator&lt;Step&gt; Steps()\r\n{\r\n    \/\/ . . . \r\n    yield return Step.Await(\r\n        this,\r\n        (thisPtr, c, s) =&gt; thisPtr.someObj.BeginOp(c, s),\r\n        (thisPtr, r) =&gt; thisPtr.retValue = thisPtr.someObj.EndOp(r),\r\n        Catch&lt;SomeException&gt;.AndHandle(this, (thisPtr, e) =&gt; thisPtr.Handle(e)));\r\n    \/\/ . . . \r\n}\r\n\r\nprivate bool Handle(SomeException exception)\r\n{\r\n    \/\/ . . . Do something with exception here . . .\r\n\r\n    \/\/ If successfully handled ...\r\n    return true;\r\n}\r\n<\/pre>\n<p>By default, any exception will transition the overarching <code>Task<\/code> to a faulted state and rethrow to the caller. However, you can provide one or more handler methods that return a <code>bool<\/code> indicating whether the exception should be handled (<code>true<\/code>) or rethrown (<code>false<\/code>).<\/p>\n<p>Here is a full use case of an async file reader. Note the use of member variables to avoid implicit capture &#8212; in general, this should improve performance due to reduced code generation and heap allocation:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\ninternal sealed class AsyncFileReader\r\n{\r\n    private readonly int bufferSize;\r\n\r\n    public AsyncFileReader(int bufferSize)\r\n    {\r\n        this.bufferSize = bufferSize;\r\n    }\r\n\r\n    public Task&lt;byte&#x5B;]&gt; ReadAllBytesAsync(string path)\r\n    {\r\n        return new ReadAllBytesAsyncOperation(path, this.bufferSize).Start();\r\n    }\r\n\r\n    private sealed class ReadAllBytesAsyncOperation : AsyncOperation&lt;byte&#x5B;]&gt;\r\n    {\r\n        private readonly string path;\r\n        private readonly int bufferSize;\r\n\r\n        private FileStream stream;\r\n        private byte&#x5B;] buffer;\r\n        private int bytesRead;\r\n\r\n        public ReadAllBytesAsyncOperation(string path, int bufferSize)\r\n        {\r\n            this.path = path;\r\n            this.bufferSize = bufferSize;\r\n        }\r\n\r\n        protected override IEnumerator&lt;Step&gt; Steps()\r\n        {\r\n            using (MemoryStream outputStream = new MemoryStream())\r\n            using (this.stream = new FileStream(this.path, FileMode.Open, FileAccess.Read, FileShare.Read, this.bufferSize, true))\r\n            {\r\n                this.buffer = new byte&#x5B;this.bufferSize];\r\n                do\r\n                {\r\n                    Console.WriteLine(&quot;&#x5B;{0}] Reading...&quot;, Thread.CurrentThread.ManagedThreadId);\r\n                    yield return Step.Await(\r\n                        this,\r\n                        (thisPtr, c, s) =&gt; thisPtr.stream.BeginRead(thisPtr.buffer, 0, thisPtr.bufferSize, c, s),\r\n                        (thisPtr, r) =&gt; thisPtr.bytesRead = thisPtr.stream.EndRead(r));\r\n                    Console.WriteLine(&quot;&#x5B;{0}] Read {1} bytes.&quot;, Thread.CurrentThread.ManagedThreadId, this.bytesRead);\r\n                    if (this.bytesRead &gt; 0)\r\n                    {\r\n                        outputStream.Write(this.buffer, 0, this.bytesRead);\r\n                    }\r\n                }\r\n                while (this.bytesRead &gt; 0);\r\n\r\n                this.Result = outputStream.ToArray();\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>Here is a snippet from the sample app included in the project, which reads a 1000000 byte file:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nAsyncFileReader reader = new AsyncFileReader(100001);\r\nTask&lt;byte&#x5B;]&gt; task = reader.ReadAllBytesAsync(path);\r\nbyte&#x5B;] readBytes = task.Result;\r\nConsole.WriteLine(&quot;Read {0} bytes.&quot;, readBytes.Length);\r\n<\/pre>\n<p>Finally, the sample output:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&#x5B;1] Reading...\r\n&#x5B;5] Read 100001 bytes.\r\n&#x5B;5] Reading...\r\n&#x5B;5] Read 100001 bytes.\r\n&#x5B;5] Reading...\r\n&#x5B;5] Read 100001 bytes.\r\n&#x5B;5] Reading...\r\n&#x5B;5] Read 100001 bytes.\r\n&#x5B;5] Reading...\r\n&#x5B;5] Read 100001 bytes.\r\n&#x5B;5] Reading...\r\n&#x5B;5] Read 100001 bytes.\r\n&#x5B;5] Reading...\r\n&#x5B;7] Read 100001 bytes.\r\n&#x5B;7] Reading...\r\n&#x5B;7] Read 100001 bytes.\r\n&#x5B;7] Reading...\r\n&#x5B;7] Read 100001 bytes.\r\n&#x5B;7] Reading...\r\n&#x5B;7] Read 99991 bytes.\r\n&#x5B;7] Reading...\r\n&#x5B;7] Read 0 bytes.\r\nRead 1000000 bytes.\r\n<\/pre>\n<p>If you&#8217;re stuck with .NET 4.0, why not give <code>AsyncOperation<\/code> a try and see how it eases the pain of async?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Writing managed asynchronous code has been possible since the advent of IAsyncResult in .NET 1.0. However, it has not been easy until async\/await in .NET 4.5. Unfortunately, there are situations where you really need to implement asynchrony but are stuck&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21,41],"tags":[],"class_list":["post-2391","post","type-post","status-publish","format-standard","hentry","category-async","category-tdd"],"_links":{"self":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/2391","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2391"}],"version-history":[{"count":0,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/2391\/revisions"}],"wp:attachment":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2391"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2391"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2391"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}