4

Assume I have a method that has void return type and that I need to await on an operation in this method.

public void someOperation()
{
    //dostuff
    var res = await someOtherOperation();
    //do some other stuff that needs res.
}

When I tried to compile this code I got the error saying someOperation has to be declare async. I don't understand why. I understand why it would if the method had a return value, but not here when it's void. or even in the case when the awaiting operation has no effect on the return value of method.
This has already been asked as a part of this question but I didn't find the answer I was looking for. This guy merely mentions:

The async keyword enables the await keyword. So any method using await must be marked async.

  • First of all, I'm not sure what it means that async keyword enables await keyword.
  • And secondly, restating my question, I'm not sure why it is required?
Community
  • 1
  • 1
atoMerz
  • 7,534
  • 16
  • 61
  • 101
  • 2
    1) You can't use the `await` operator in a method that is not declared `async`. Thus it *enables* the operator. 2) I'm not sure I understand what your question is, "why it is required?" It is required because that's how the languge works. What exactly is the problem? – Kirk Woll Dec 03 '14 at 18:13
  • I mean, is it supposed to be there just to conform to existing design? The designers didn't want to make an exception in this case? Because from the way I look at it it isn't required. The method would work just fine without the caller needing to know it is `async`. – atoMerz Dec 03 '14 at 18:16

3 Answers3

11

I don't understand why.

Because you need to tell the compiler that you're trying to write an async method. That's exactly what the document you're quoting means.

The compiler could infer that from whether or not your method includes any await expressions - but that would mean you could comment out one line of a method and the whole method's behaviour would radically change. (Think about exception handling, for example...)

It also improves readability - it means anyone reading your code knows this is an async method right from the start.

So basically, the answers are:

  • You need to because the language specification requires you to. The compiler is implementing the language specification.
  • The language specification requires you to because it reduces the element of surprise.
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Jon, is there a duplicate of this? If not, then this may become the canonical "why do I need to make my method `async`" question. – John Saunders Dec 03 '14 at 18:15
  • @JohnSaunders: Not that I know of off-hand. There may well be, but I don't know of it right now :) – Jon Skeet Dec 03 '14 at 18:16
  • @JohnSaunders The canonical reference for this, in my mind is [Eric's blog post](http://blogs.msdn.com/b/ericlippert/archive/2010/11/11/whither-async.aspx) on the subject. It includes both a more in depth exporation of the points Jon summarized here, as well as several others, such as avoiding breaking changes (what if someone had a method called `await` pre-5.0?). – Servy Dec 03 '14 at 18:57
11

Asynchronous methods must be marked async. The async and await keywords are paired together, primarily for backwards-compatibility reasons; await was a valid identifier (not a keyword), so when it was added to the language, they also added the async keyword.

Alternatively, they could have gone with a multi-word keyword for await, such as await for. However, the language design team decided to go with the pairing, since it clearly and explicitly marks all async methods - it's easier for both compilers and humans to parse.

I have a blog post on the subject, with links to Eric Lippert's definitive blog post as well as discussions in blog comments, Channel9 forums, MSDN forums, and of course right here on Stack Overflow.

Note that the natural return type of an async method without a result value is Task, not void. void is an unnatural return type for async methods. So your default reaction when seeing the "await operator must be within an async method" error should be to mark it async and change the return type from void to Task:

public async Task someOperationAsync()
{
  //dostuff
  var res = await someOtherOperationAsync();
  //do some other stuff that needs res.
}

This follows one of the best practices in my MSDN article on the subject: avoid async void. async void was allowed by the language designers for event handlers (or code that is logically an event handler, like ICommand.Execute); any other usage is going to cause problems.

Community
  • 1
  • 1
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
0

Because they must work in pair in C#. It is the rule.

The “async” keyword enables the “await” keyword in that method and changes how method results are handled. That’s all the async keyword does! It does not run this method on a thread pool thread, or do any other kind of magic. The async keyword only enables the await keyword (and manages the method results).

Hui Zhao
  • 655
  • 1
  • 10
  • 20