{"id":2713,"date":"2008-03-16T15:59:32","date_gmt":"2008-03-16T15:59:32","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/pfxteam\/2008\/03\/16\/wrapping-an-apm-implementation-with-futuret\/"},"modified":"2008-03-16T15:59:32","modified_gmt":"2008-03-16T15:59:32","slug":"wrapping-an-apm-implementation-with-futuret","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/wrapping-an-apm-implementation-with-futuret\/","title":{"rendered":"Wrapping an APM implementation with Future"},"content":{"rendered":"<p>In a previous post, I talked about <a href=\"https:\/\/blogs.msdn.com\/pfxteam\/archive\/2008\/02\/29\/7960146.aspx\">implementing the Asynchronous Programming Model<\/a> pattern using Future&lt;T&gt; from <a href=\"https:\/\/www.microsoft.com\/downloads\/details.aspx?FamilyID=e848dc1d-5be3-4941-8705-024bc7f180ba\">Parallel Extensions to the .NET Framework<\/a>.&nbsp; It&#8217;s also possible to go in the opposite direction, to create a Future&lt;T&gt; from an existing APM implementation.<\/p>\n<p>As has been shown in previous examples, in this example we&#8217;ll take advantage of the &#8220;promise&#8221; capabilities provided by Future&lt;T&gt;.&nbsp; This allows a Future&lt;T&gt; to be created without a Func&lt;T&gt; delegate, such that the future&#8217;s Value and Exception properties can be set explicitly, but only once; any thread waiting on the Future&lt;T&gt; will block until one of these properties is set.<\/p>\n<blockquote>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt;line-height: normal\"><span style=\"font-size: 10pt;font-family: consolas\"><span style=\"color: blue\">static<\/span> <span style=\"color: #2b91af\">Future<\/span>&lt;T&gt; Create&lt;T&gt;(<br>&nbsp;&nbsp;&nbsp; <span style=\"color: #2b91af\">Action<\/span>&lt;<span style=\"color: #2b91af\">AsyncCallback<\/span>&gt; beginFunc, <br>&nbsp;&nbsp;&nbsp; <span style=\"color: #2b91af\">Func<\/span>&lt;<span style=\"color: #2b91af\">IAsyncResult<\/span>, T&gt; endFunc)<br><\/span><span style=\"font-size: 10pt;font-family: consolas\">{<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: blue\">var <\/span>f = <span style=\"color: #2b91af\">Future<\/span>&lt;T&gt;.Create();<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp; <\/span>beginFunc(iar =&gt; {<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: blue\">try<\/span> { f.Value = endFunc(iar); }<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: blue\">catch<\/span> (<span style=\"color: #2b91af\">Exception<\/span> e) { f.Exception = e; }<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp; <\/span>});<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: blue\">return<\/span> f;<br><\/span><span style=\"font-size: 10pt;line-height: 115%;font-family: consolas\">}<\/span><\/p>\n<\/blockquote>\n<p>This Create&lt;T&gt; method first creates a Future&lt;T&gt; as a promise.&nbsp; It then calls a delegate provided by the caller to start the asynchronous action using the relevant BeginXx method; as an argument to that action, this code passes a delegate that will be called back by the asynchronous operation when it completes; the APM method will pass an IAsyncResult, which will then be passed in this callback to the endFunc delegate provided by the caller.&nbsp; That endFunc will call the EndXx method, and will use the resulting value or exception to set the Future&lt;T&gt;.<\/p>\n<p>As an example of using this, consider a FileStream.&nbsp; FileStream exposes a BeginRead method:<\/p>\n<blockquote>\n<p class=\"MsoNormal\"><span style=\"font-size: 10pt;color: #2b91af;line-height: 115%;font-family: consolas\">IAsyncResult<\/span><span style=\"font-size: 10pt;line-height: 115%;font-family: consolas\"> BeginRead(<br>&nbsp;&nbsp;&nbsp; <span style=\"color: blue\">byte<\/span>[] array, <span style=\"color: blue\">int<\/span> offset, <span style=\"color: blue\">int<\/span> numBytes, <span style=\"color: #2b91af\"><br>&nbsp;&nbsp;&nbsp; AsyncCallback<\/span> userCallback, <span style=\"color: blue\">object<\/span> stateObject)<\/span><\/p>\n<\/blockquote>\n<p>as well as a corresponding EndRead method:<\/p>\n<blockquote>\n<p class=\"MsoNormal\"><span style=\"font-size: 10pt;color: blue;line-height: 115%;font-family: consolas\">int<\/span><span style=\"font-size: 10pt;line-height: 115%;font-family: consolas\"> EndRead(<span style=\"color: #2b91af\">IAsyncResult<\/span> asyncResult);<\/span><\/p>\n<\/blockquote>\n<p>If we want to create a Future&lt;T&gt; that represents an asynchronous read operation on a FileStream, we could do so with our new Create method as follows:<\/p>\n<blockquote>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt;line-height: normal\"><span style=\"font-size: 10pt;color: blue;font-family: consolas\">var<\/span><span style=\"font-size: 10pt;font-family: consolas\"> readFuture = Create&lt;<span style=\"color: blue\">int<\/span>&gt;(<br>&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 10pt;font-family: consolas\">ac =&gt; fs.BeginRead(buffer, 0, buffer.Length, ac, <span style=\"color: blue\">null<\/span>),<br>&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 10pt;line-height: 115%;font-family: consolas\">fs.EndRead);<\/span><\/p>\n<\/blockquote>\n<p>I can now go off and do something else, and when I later get readFuture&#8217;s Value, I&#8217;ll block until the asynchronous operation completes (or return immediately with the result if it&#8217;s already completed).&nbsp; If the FileStream was created to support asynchronous I\/O operations and if the underlying version of Windows supports asynchronous I\/O, while the read request is happening, no threads will be used, and yet I&#8217;ll still have a valid Future&lt;T&gt; to represent the operation.<\/p>\n<p>There are of course other possible designs for and implementations of such a Create method.&nbsp; An alternate implementation might look like this:<\/p>\n<blockquote>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt;line-height: normal\"><span style=\"font-size: 10pt;font-family: consolas\"><span style=\"color: blue\">static<\/span> <span style=\"color: #2b91af\">Future<\/span>&lt;T&gt; Create&lt;T&gt;(<br>&nbsp;&nbsp;&nbsp; <span style=\"color: #2b91af\">IAsyncResult<\/span> iar, <span style=\"color: #2b91af\">Func<\/span>&lt;<span style=\"color: #2b91af\">IAsyncResult<\/span>, T&gt; endFunc)<br><\/span><span style=\"font-size: 10pt;font-family: consolas\">{<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: blue\">var<\/span> f = <span style=\"color: #2b91af\">Future<\/span>&lt;T&gt;.Create();<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">ThreadPool<\/span>.RegisterWaitForSingleObject(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iar.AsyncWaitHandle, <span style=\"color: blue\">delegate <\/span><\/span><span style=\"font-size: 10pt;font-family: consolas\">{<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: blue\">try<\/span> { f.Value = endFunc(iar); }<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: blue\">catch<\/span> (<span style=\"color: #2b91af\">Exception<\/span> e) { f.Exception = e; }<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp; <\/span>}, <span style=\"color: blue\">null<\/span>, -1, <span style=\"color: blue\">true<\/span>);<br><\/span><span style=\"font-size: 10pt;font-family: consolas\"><span>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: blue\">return<\/span> f;<br><\/span><span style=\"font-size: 10pt;line-height: 115%;font-family: consolas\">}<\/span><\/p>\n<\/blockquote>\n<p>Here&#8217;s I&#8217;m using the same promise functionality of Future&lt;T&gt;, but instead of using the callback functionality of the APM, I&#8217;m relying on ThreadPool&#8217;s RegisterWaitForSingleObject functionality.&nbsp; When the provided IAsyncResult&#8217;s AsyncWaitHandle is signaled (which will happen when the asynchronous operation completes), my delegate will be called to call endFunc and set the Future&lt;T&gt;&#8217;s Value or Exception property as shown previously.&nbsp; This version can be used as follows:<\/p>\n<blockquote>\n<p class=\"MsoNormal\"><span style=\"font-size: 10pt;color: blue;line-height: 115%;font-family: consolas\">var<\/span><span style=\"font-size: 10pt;line-height: 115%;font-family: consolas\"> readFuture = Create&lt;<span style=\"color: blue\">int<\/span>&gt;(<br>&nbsp;&nbsp;&nbsp; fs.BeginRead(buffer, 0, buffer.Length, <span style=\"color: blue\">null<\/span>, <span style=\"color: blue\">null<\/span>), <br>&nbsp;&nbsp;&nbsp; fs.EndRead);<\/span><\/p>\n<\/blockquote>\n<p>Now comes the interesting question&#8230;<\/p>\n<p>We don&#8217;t currently have a Create method like this on Future&lt;T&gt;.&nbsp; You can write your own as has been shown here, but is this important enough for us to include one on Future&lt;T&gt; itself?&nbsp; Do you have such a need in your applications?&nbsp; Should we provide deeper support to further enable this kind of integration? Let us know \ud83d\ude42<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In a previous post, I talked about implementing the Asynchronous Programming Model pattern using Future&lt;T&gt; from Parallel Extensions to the .NET Framework.&nbsp; It&#8217;s also possible to go in the opposite direction, to create a Future&lt;T&gt; from an existing APM implementation. As has been shown in previous examples, in this example we&#8217;ll take advantage of the [&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":[7911,7909,7912,7914],"class_list":["post-2713","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pfxteam","tag-code-samples","tag-parallel-extensions","tag-task-parallel-library","tag-threadpool"],"acf":[],"blog_post_summary":"<p>In a previous post, I talked about implementing the Asynchronous Programming Model pattern using Future&lt;T&gt; from Parallel Extensions to the .NET Framework.&nbsp; It&#8217;s also possible to go in the opposite direction, to create a Future&lt;T&gt; from an existing APM implementation. As has been shown in previous examples, in this example we&#8217;ll take advantage of the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/2713","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=2713"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/2713\/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=2713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=2713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=2713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}