<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Why must async methods return Task?</title><link>http://blogs.msdn.com/b/lucian/archive/2012/11/22/why-must-async-methods-return-task.aspx</link><description>We all know that async methods return Task or Task(Of T): 
 Async Function GetNameAsync() As Task ( Of String ) Await Task .Delay(10) Return "ernest" End Function 
 Sometimes, advanced users ask for the ability to return different types out of an async</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>re: Why must async methods return Task?</title><link>http://blogs.msdn.com/b/lucian/archive/2012/11/22/why-must-async-methods-return-task.aspx#10371235</link><pubDate>Sat, 24 Nov 2012 01:58:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10371235</guid><dc:creator>Lucian Wischik, MSFT</dc:creator><description>&lt;p&gt;@Stefan - thanks for the serialization scenario. We&amp;#39;d discussed serialization in our design meetings. It&amp;#39;s a big topic, so I wrote a separate blog article with a possible implementation of serialization. (Sorry for the missing spaces... this blog platform doesn&amp;#39;t let me past code with syntax highlighting unless I go via raw HTML markup, which is losing spaces!)&lt;/p&gt;
&lt;p&gt;How would I expect a solution to generalize to Yield? Here are some examples. (I also count f3 and f4 as the interesting examples that I might want to return).&lt;/p&gt;
&lt;p&gt;Sub f1(lambda As IAsyncAction) ...&lt;/p&gt;
&lt;p&gt;Sub f2(Of T)(lambda As IAsyncOperation(Of TR)) ...&lt;/p&gt;
&lt;p&gt;Sub f3(Of T,U)(lambda As IAsyncOperationWithProgress(Of TR,TP)) ...&lt;/p&gt;
&lt;p&gt;Sub f4(Of T)(lambda As IObservable(Of T))&lt;/p&gt;
&lt;p&gt;Sub f5(Of T)(lambda As IAsyncEnumerable(Of T))&lt;/p&gt;
&lt;p&gt;f1(... : Return : ...)&lt;/p&gt;
&lt;p&gt;f2(... : Return 15 : ...) &amp;nbsp;&amp;#39; infers TR=integer&lt;/p&gt;
&lt;p&gt;f3(... : Yield 12 : ... : Return &amp;quot;hello&amp;quot;) &amp;nbsp;&amp;#39; infers TR=string, TP=integer&lt;/p&gt;
&lt;p&gt;f4(... : Return 7 : Return 15 : Return 12 : Return ) &amp;#39; infers T=integer&lt;/p&gt;
&lt;p&gt;f5(... : If b Then Return : ... : Yield 15) &amp;#39; infers T=integer&lt;/p&gt;
&lt;p&gt;In f5 the Yield statement implies that the first generic parameter is the dominant type of all yield expressions, but in f3 it implies that the SECOND generic parameter is the dominant type of all yield expressions.&lt;/p&gt;
&lt;p&gt;In f1/f5 the Return operand must be void, but in f2/f3 the dominant type of return operands is taken as the first generic parameter. And in f4 we use multiple returns for a function with multiple return-values, or a void return to indicate the end of the sequence.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ll grant you that multi-return f4 might be trying to be too clever for its own good. But even just the fact that Yield sometimes binds to the first generic parameter and sometimes to the second is too ugly.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10371235" width="1" height="1"&gt;</description></item><item><title>re: Why must async methods return Task?</title><link>http://blogs.msdn.com/b/lucian/archive/2012/11/22/why-must-async-methods-return-task.aspx#10371234</link><pubDate>Sat, 24 Nov 2012 01:46:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10371234</guid><dc:creator>Lucian Wischik, MSFT</dc:creator><description>&lt;p&gt;@Stephen Clearly -- good point. Yes covariance would be a reason for ITask(Of T).&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10371234" width="1" height="1"&gt;</description></item><item><title>re: Why must async methods return Task?</title><link>http://blogs.msdn.com/b/lucian/archive/2012/11/22/why-must-async-methods-return-task.aspx#10370980</link><pubDate>Thu, 22 Nov 2012 18:55:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10370980</guid><dc:creator>Stefan Wenig</dc:creator><description>&lt;p&gt;(cont&amp;#39;d)&lt;/p&gt;
&lt;p&gt;You gave three reasons for not doing this. I’d like to ask you to elaborate on the first two:&lt;/p&gt;
&lt;p&gt;-	How would you expect a solution to generalize to Yield? (Btw, we can easily do our trick using iterators, we just need to install a reflection-based serialization surrogate, which works as long as all your local variables are serializable. But the syntax is awkward, e.g. instead of calling await EditObject, we’d have to do foreach (var x in EditObject) yield return x; plus there are no return values.)&lt;/p&gt;
&lt;p&gt;-	What interesting return types would it not work with? (If you think about IAsyncOperation&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt;, a possible workaround may be an interface IAsyncEnuerableOperation&amp;lt;T&amp;gt; deriving from the former. This might not resolve every problem, but there have always been border cases in C# that the type system just won’t let you do. And there have been solutions, like dynamic interface proxies.)&lt;/p&gt;
&lt;p&gt;On the third reason, I disagree strongly. You write “this kind of complex and arbitrary restriction is unprecedented and ugly”. C# already has some features that use behind-the-scene transformation, like foreach (for .Dispose()) and LINQ query expressions. Providing any unresolvable overloads for Select(), or using type parameters that cannot be inferred, will result in compilation errors. Frankly, I don’t see a real difference here. On the other hand, no single feature in C# today relies on such a complex framework type. All other dependencies of C# are a) implicit (the type does not usually show in the source code) and b) use very primitive types, like Object, ValueType or MulticastDelegate. Linking a compiler feature to a complex type that is not serializable is what is unprecedented.&lt;/p&gt;
&lt;p&gt;We discussed this at some length and think that solution #1 would be a very useful addition that does not really bring unprecedented, unexpected or ugly behavior to C#.&lt;/p&gt;
&lt;p&gt;We’d love to see you pick up this idea again for some hypothetical future version of C# ;-)&lt;/p&gt;
&lt;p&gt;Thanks for listening!&lt;/p&gt;
&lt;p&gt;Cheers, Stefan&lt;/p&gt;
&lt;p&gt;PS: sorry for all the curly braces on your VB blog, but I assume you and most of your readers read C# fluently, and I can hardly read, let alone write VB. Just figuring out what that AsyncFunction() is took me some time (the missing space didn&amp;#39;t help).&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10370980" width="1" height="1"&gt;</description></item><item><title>re: Why must async methods return Task?</title><link>http://blogs.msdn.com/b/lucian/archive/2012/11/22/why-must-async-methods-return-task.aspx#10370979</link><pubDate>Thu, 22 Nov 2012 18:55:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10370979</guid><dc:creator>Stefan Wenig</dc:creator><description>&lt;p&gt;Hi Lucian,&lt;/p&gt;
&lt;p&gt;I’m working with Michael who asked about serialization above. I’d like to elaborate a bit. What we’re trying to do is creating a way to create request-spanning methods for ASP.NET using continuation-passing style.&lt;/p&gt;
&lt;p&gt;Here’s some simple pseudo code (not intended to show the potential of CPS web programming, just how it could work):&lt;/p&gt;
&lt;p&gt;async Task&amp;lt;string&amp;gt; GetInput (string msg) {…}&lt;/p&gt;
&lt;p&gt;async Task&amp;lt;bool&amp;gt; Confirm (string msg) {…}&lt;/p&gt;
&lt;p&gt;async Task&amp;lt;void&amp;gt; EditObject (MyObject obj) &lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; await ShowWebForm (“EditObject.aspx”, obj);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;async Task CreateObject ()&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp;int name = await GetInput (“object name”);&lt;/p&gt;
&lt;p&gt; &amp;nbsp;var obj = MyObject (name);&lt;/p&gt;
&lt;p&gt; &amp;nbsp;await EditObject (obj);&lt;/p&gt;
&lt;p&gt; &amp;nbsp;if (await Confirm (“do you want to keep this?”))&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;Repository.Add (obj);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The system could execute until a call to ShowWebForm occurs, which could somehow pass the parameters it receives and call a page using Server.Transfer. The current thread then ends. At the next request, execution would continue right after this call to ShowWebForm. Our problem however is that Task&amp;lt;T&amp;gt; and Task are such awfully complex and tangled objects that we don’t see a way to safely serialize and deserialize them, so this would not work with state servers. &lt;/p&gt;
&lt;p&gt;This is our priority, so if the problem of serializing Tasks is solved, everything else is just of theoretical interest to us. But still, here it is:&lt;/p&gt;
&lt;p&gt;Replacing Task&amp;lt;T&amp;gt; with MyTask&amp;lt;T&amp;gt; could solve the problem by using a simpler structure that serializes easily. Your solution #1 would solve this beautifully. (There should be a non-generic type corresponding to Task, i.e. Task&amp;lt;void&amp;gt;, though).&lt;/p&gt;
&lt;p&gt;(to be continued)&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10370979" width="1" height="1"&gt;</description></item><item><title>re: Why must async methods return Task?</title><link>http://blogs.msdn.com/b/lucian/archive/2012/11/22/why-must-async-methods-return-task.aspx#10370848</link><pubDate>Thu, 22 Nov 2012 07:34:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10370848</guid><dc:creator>Michael</dc:creator><description>&lt;p&gt;Thanks for the lengthy explanation. Enjoyed reading it :) Since I (well, the team I work in) are one of the Scenario #3 proponents, I have a follow up: We didn&amp;#39;t want to replace Task to substitute an arbitrary adapter to our own framework but so we can replace Task with a (lightweight) implementation that is serializable. Do you have any design suggestions along the lines of what you proposed for Scenario #3&lt;/p&gt;
&lt;p&gt;Regards, Michael&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10370848" width="1" height="1"&gt;</description></item><item><title>re: Why must async methods return Task?</title><link>http://blogs.msdn.com/b/lucian/archive/2012/11/22/why-must-async-methods-return-task.aspx#10370795</link><pubDate>Thu, 22 Nov 2012 02:05:39 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10370795</guid><dc:creator>Stephen Cleary</dc:creator><description>&lt;p&gt;Enjoyed your post!&lt;/p&gt;
&lt;p&gt;With my work in async, I have on a few occasions wished for ITask&amp;lt;T&amp;gt; - not so I can return my own implementation, but so I could use generic variance. There are a few situations where that would be really useful. Well, maybe someday generic variance will be extended to classes... :)&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10370795" width="1" height="1"&gt;</description></item></channel></rss>