9

So I was asking this question about async , and I thought that it it's just a sugar syntax for :

Task<..>...ContinueWith...

And finally inspect the Result property.

I even asked a question about it here and I was told :

enter image description here

enter image description here

But Today I was corrected by Jon Skeet

" It's a very long way from that".

So what are the core differences between those 2 approaches ?

Community
  • 1
  • 1
Royi Namir
  • 144,742
  • 138
  • 468
  • 792

1 Answers1

15

It is adding a continuation - but manually constructing that continuation can be very painful, due to the need to carry around all the information about where we'd got to and what the local state is.

As a very simple example, I suggest you try to come up with the equivalent of this async method:

public static async Task<int> SumTwoOperationsAsync()
{
    var firstTask = GetOperationOneAsync();
    var secondTask = GetOperationTwoAsync();
    return await firstTask + await secondTask;
}

// These are just examples - you don't need to translate them.
private async Task<int> GetOperationOneAsync()
{
    await Task.Delay(500); // Just to simulate an operation taking time
    return 10;
}

private async Task<int> GetOperationTwoAsync()
{
    await Task.Delay(100); // Just to simulate an operation taking time
    return 5;
}

Really try to come up with the equivalent of the first method. I think you'll find it takes quite a lot of code - especially if you actually want to get back to an appropriate thread each time. (Imagine code in that async method also modified a WPF UI, for example.) Oh, and make sure that if either of the tasks fails, your returned task fails too. (The async method will actually "miss" the failure of the second task if the first task also fails, but that's a relatively minor problem IMO.)

Next, work out how you'd need to change your code if you needed the equivalent of try/finally in the async method. Again, that'll make the non-async method more complicated. It can all be done, but it's a pain in the neck.

So yes, it's "just" syntactic sugar. So is foreach. So is a for loop (or any other kind of loop). In the case of async/await, it's syntactic sugar which can do really rather a lot to transform your code.

There are lots of videos and blog posts around async, and I would expect that just watching/reading a few of them would give you enough insight to appreciate that this is far from a minor tweak: it radically changes how practical it is to write large amounts of asynchronous code correctly.

Additionally, being pattern-based, async/await doesn't only work on Task / Task<T>. You can await anything which adheres to the awaitable pattern. In practice very few developers will need to implement the pattern themselves, but it allows for methods like Task.Yield which returns a YieldAwaitable rather than a task.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • So no, it's not "just" syntactic sugar! See to managed IL. You will be very surprised at the difference between Task with and without using async/await. – hVostt Feb 16 '14 at 16:59
  • 3
    @hVostt: I've decompiled *lots* of async/await code. I won't be surprised at the difference any more, but I still think it's "just" syntactic sugar. It's massively useful and quite complicated syntactic sugar, and sometimes the results are code which couldn't be represented in *exactly* that IL using C# 4 - but fundamentally it's not doing anything that really couldn't be done before. It's not like generics, which was a fundamental shift in the type system. This is just the compiler being smart. I'm not trying to underplay how useful it is - I *love* async. But it's still syntactic sugar IMO. – Jon Skeet Feb 16 '14 at 17:02
  • @hVostt: From the Wikipedia definition of syntactic sugar: "Specifically, a construct in a language is called syntactic sugar if it can be removed from the language without any effect on what the language can do: functionality and expressive power will remain the same." That sounds like async/await to me. – Jon Skeet Feb 16 '14 at 17:03
  • var - is syntax sugar, LINQ query expression for LINQ fluent is syntax sugar, autoproperties is syntax sugar. async/await is not syntax sugar. because if you can something do without that syntax, it does not mean that it is syntax sugar. async/await generates a LOT of additional code that creates a finite state machine. how you can call it simple sugar? – hVostt Feb 16 '14 at 17:08
  • should not always blindly trust excerpts from Wikipedia. sometimes worth some thought :) – hVostt Feb 16 '14 at 17:09
  • @hVostt: Yes, it really does. Did I say it was simple? No. Read the quote from Wikipedia, or ideally the whole article. Async/await doesn't affect what *can* be done with the language - it affects how feasible it is to do that. And I'm not blindly trusting excerpts from Wikipedia - it aligns with the meaning of syntactic sugar I've *always* used and seen used. I include iterator blocks, `foreach`, `for` loops etc as syntactic sugar too. I've got a pretty clear definition of what syntactic sugar is - do you? (If so, can you state it please?) – Jon Skeet Feb 16 '14 at 17:10
  • By the way, Jeffrey Richter does not consider this syntactic sugar – hVostt Feb 16 '14 at 17:11
  • @hVostt: You shouldn't always blindly trust Jeffrey Richter :) (If you have a reference for saying he doesn't consider it syntactic sugar, I'd like to see it though.) – Jon Skeet Feb 16 '14 at 17:12
  • if that reason, then the entire C # language is syntactic sugar. usually sugar hides a some of maintainable code. but if syntax sets a completely new style of programming, it is definitely not sugar. despite what wikipedia says :) – hVostt Feb 16 '14 at 17:14
  • I just now book by Jeffrey Richter in hands, I personally did not ask :) never seen a syntactic sugar weighty devoted a whole chapter in the book – hVostt Feb 16 '14 at 17:16
  • @hVostt: No, it's not all syntactic sugar. As I said, generics are not syntactic sugar. Type declarations aren't syntactic sugar. `goto` isn't syntactic sugar. (I can go on...) Without those language features, the language would lose functionality and expressive power. But anyway, you clearly have your own definition for syntactic sugar - I'll stick to the one which is not only in Wikipedia, but is also in accordance with how I've always seen the term. – Jon Skeet Feb 16 '14 at 17:16
  • @hVostt: So are you *inferring* that Richter doesn't believe it's syntactic sugar, just based on the fact that it has its own chapter? Because plenty of my chapters in C# in Depth are dedicated to syntactic sugar - chapters 5, 6, 8, 10, 11 and 15, in fact. So you mustn't assume that just because an author thinks a topic deserves its own chapter means they don't believe that topic is syntactic sugar. – Jon Skeet Feb 16 '14 at 17:18
  • Why, then, this "sugar" does not want to work in .NET 4.0? entered "sugar" in C# 3 worked perfectly in .NET 2.0 – hVostt Feb 16 '14 at 17:19
  • @hVostt: It does, actually, if you use an extra library (not a CLR change): http://www.nuget.org/packages/microsoft.bcl.async. Note that similarly you can't use LINQ in .NET 2.0 without libraries. – Jon Skeet Feb 16 '14 at 17:20
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/47604/discussion-between-jon-skeet-and-hvostt) – Jon Skeet Feb 16 '14 at 17:20
  • @RoyiNamir: Ack, but in future mailing me or adding a comment on the blog post would be more suitable. – Jon Skeet Mar 22 '14 at 13:01
  • @JonSkeet I tried , but The comments there were closed for some reason ... however - I did see (now) your email in profile.... next time :-)) – Royi Namir Mar 22 '14 at 13:10