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?
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.
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.
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).
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 months ago.
Improve this question
I'm completely confused.
It says here:
Async methods can have the following return types:
Task, for an async method that performs an operation but returns no
value.
Task <TResult>, for an async method that returns a value.
void, for an event handler.
Starting with C# 7.0, any type that has an accessible GetAwaiter
method. The object returned by the GetAwaiter method must implement
the System.Runtime.CompilerServices.ICriticalNotifyCompletion
interface.
Starting with C# 8.0, IAsyncEnumerable<T>, for an async method that
returns an async stream.
Question 1. Why write about tasks if Task and Task<Result> fit the "GetAwaiter" criterion?
Question 2. Here I got the answer that the IAsyncEnumerable<T> point is more about await. Then what about everything else? Can someone clearly explain what each keyword applies to without big examples?
What types can return async methods - list or criteria? And what types can the await keyword or their criteria apply to?
Examples of answers how I would like:
Keyword async applicable for return values (async methods can return values): type1, type2, typeN, or any type with specific characteristics (for example ... some characteristics).
Keyword await applicable for awaitable types: type1, type2, typeN, or type with specific characteristics (for example contains GetAwaiter).
Question 3. Speaking of void we mean only the return value of the async method. Can void be the awaitable type? Can someone give an example of a void awaiting?
Why write about tasks if Task and Task fit the "GetAwaiter" criterion?
Probably because Task/Task<Result> will be used in 90% or so of all cases. It hints to a new developer to just use these types, and not try to implement a custom type for this, or spending extra time looking up the documentation.
Question 2. Here I got the answer that the IAsyncEnumerable point is more about await. Then what about everything else? Can someone clearly explain what each keyword applies to without ten-story examples?
async is used to tell the compiler to rewrite the method into a state machine, so that different parts of the method can be run at different times. If the method returns anything, this needs to be wrapped in something that allow the caller to use the result when it is actually produced.
await is used in an async method suspend execution of the method until the awaited value is available. I.e. it marks where the compiler will split the method into the different sections.
I think you are making this more complicated then it needs to be:
Use Task when you do not need to return a value
Use Task<Result> when you return a value
Use IAsyncEnumerable<T> when producing a sequence of values asynchronously. I.e. each value is produced by a separate network/Database call. Contrast with Task<T[]> when one IO call produces a sequence of values.
Use ValueTask when you want to minimize overhead. See Understanding the Whys, Whats, and Whens of ValueTask
Use void when you are forced to. I.e. UI event handlers.
Use a custom type when you have some special reason to. This should be quite rare, I would expect 99% of developers never to write any such implementation.
Speaking of void we mean only the return value of the async method, is void not the expected type?
A normal non-async void method can actually produce two results:
Nothing
An exception
And the result is only produced once the method has reached its end. Awaiting a method returning a Task replicates this behavior. An async void method however does not. Since there is nothing to await, the caller have no way of knowing when, and if the method reaches its end. And exceptions may be lost, without anyone knowing it occurred. This is acceptable for things like UI events, after all, why does the UI system does not really care about what happens when a button is pressed, it is up to the developer to do things like handling exceptions. But in most other cases, Task should be used to represent a synchronous void-method.
As far as I know WebRequest.GetResponseAsync() can be awaited and is asynchonous.
But when I look at its source code at https://referencesource.microsoft.com/#System/net/System/Net/WebRequest.cs,99a2a9c8ebc067dc
it isn't defined with the "async" keyword.
I thought you cannot await a method that is not defined as "async"?
I thought you cannot await a method that is not defined as "async"?
This is a kind of "shorthand" way of thinking about it that can be useful while initially learning async, but falls apart when you gain more knowledge about async/await. There are two concepts that are not quite right in this sentence.
First, code cannot await a method. What actually happens is that the method is called, exactly like any other method. That method returns a value - an awaitable type - and it is that return value that is actually awaited. It's common for us to talk about "awaiting a method", but that's just shorthand for "calling a method and awaiting its return value", which is more accurate but too awkward for most conversation.
Second, async is just one way to create an awaitable return value (which can then be awaited). There are several other ways as well. For example, Task<T>.Factory.FromAsync is commonly used if you have an API that uses the older APM asynchronous pattern, and you want to use it with await. In that case, you would normally write wrapper methods that return Task<T> and are implemented using Task<T>.Factory.FromAsync (without async). Another common approach is to use TaskCompletionSource<T>, which can create a Task<T> around any kind of logical "future event".
To put it another way, async is an implementation detail. This concept is further enforced by the fact that interface methods can be declared as returning Task and awaited, but only method implementations can be declared with async.
Summary: In a library method, when should I use the async and await keywords instead of returning a Task directly?
I believe my question is related to this one. However, that question is about .NET 4.0 and the TPL, while I'm using .NET 4.6 with the async and await keywords. So, I think my question might get different answers because these keywords didn't exist when the linked question was answered.
Explanation: I'm writing a simple wrapper for an external WCF service and the wrapper makes multiple SendAsync calls. Now I think that each wrapper method should just return a Task<> directly without being awaited. My understanding is that async/await should be used on the application layer, and not within a library.
So, for example, here is the approach that I think I should take for each wrapper method:
private Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return _service.SendAsync(request);
}
But on the Internet, I found several posts that use this approach instead:
private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return await _service.SendAsync(request).ConfigureAwait(false);
}
And here is another example that I found on technet:
async Task PutTaskDelay()
{
await Task.Delay(5000);
}
private async void btnTaskDelay_Click(object sender, EventArgs e)
{
await PutTaskDelay();
MessageBox.Show("I am back");
}
So, when should I use the second approach (the one that includes the async and await keywords)? Why not just return a whole Task without making PutTaskDelay async? I think that I should return Task directly whenever it is possible, and use async/await to get a final result in the application layer only. Am I right? If not, what is the difference between the two approaches that I show here?
My concern: When the async and await keywords are used, it seems that it just provides additional work to the compiler without any benefit.
Should I use async await in library?
It all depends. If you're going to take advantage of the asynchronous programming paradigm, then the answer is "yes," the async and await keywords are needed most of the time. More than likely, you will find yourself needing to use async/await. That is because in most situations it would be difficult to use only Task and Task<T> as you will more than likely need to reason about the results of the async operations that you invoke.
Additionally, based on your question it seems as though you may have some confusion about the keywords themselves and how they relate to the Task and Task<T> types. Allow me to clarify this for you.
The async keyword allows a method to use the await keyword. The best practice is to have all async methods return either Task or Task<T> unless you are unable to (for example, a button click event handler as you demonstrated above).
Methods that return Task or Task<T> represent asynchronous operations. When you are in a library it is suggested to always use .ConfigureAwait(false) for reasons detailed here. Additionally, I always point people to this detailed article on the subject.
To differentiate the two approaches in your question:
The method below returns a Task<SignResponse>. This is an async operation that represents the work to sign in. The method can be awaited by the caller to get SignResponse.
private Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return _service.SignAsync(request);
}
Likewise, this version does the same thing...except that the async/await keywords are not needed. The reason they are not needed is that the method itself does not need to use SignResponse and therefore it could simply return Task<SignResponse> as shown above. And as you indicated in your question, there is indeed a penalty when you use the async/await keywords when they are not needed. Doing so adds an extra state machine step as the result is yielded, since its awaited.
private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return await _service.SignAsync(request).ConfigureAwait(false);
}
Finally, if you needed to reason about the response, you could use the aforementioned keywords to do so like this:
private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
var result = await _service.SignAsync(request).ConfigureAwait(false);
if (result.SomeProperty == SomethingWeCareToCheck)
{
_log.Log("Wow, this was un-expected...");
}
return result;
}
Don't take my word for it, because I never understood async/await that well, but what bothered me most about the idea was that all methods using async had to be marked as async as well, which annoyed me to no end.
I guess in a library giving people the option to choose how to use the methods is a good thing, so you should use async, however I always found it more clear to explicitly use the Tasks directly.
I am experimenting with the new async and await keywords. I produced the following asynchronous function:
private async static Task<string> GetStringAsync(string pageAddress)
{
HttpClient client = new HttpClient();
return client.GetStringAsync(pageAddress);
}
I understand that I am returning a Task<String> and can await the result from another method. This method works fine. My question is what happens (under the hood as it were) when I replace the second line of the above function with the following (notice the introduction of the await keyword):
return await client.GetStringAsync(pageAddress);
The function behaves in exactly the same way! Remember the function returns Task<string> not string. Is the await keyword here degenerate? Does the compiler simply strip it from my code?
The answer to this question is too large to post here given your likely current level of understanding. What you should do is start by reading my MSDN article and then Mads' MSDN article; they are a good beginner introduction to the feature and Mads describes how it is implemented. You can find links here:
http://blogs.msdn.com/b/ericlippert/archive/2011/10/03/async-articles.aspx
Then if you are interested in the theory underlying the feature you should start by reading all my articles on continuation passing style:
http://blogs.msdn.com/b/ericlippert/archive/tags/continuation+passing+style/
Start from the bottom. Once you understand the notion of continuation, you can then read my series of articles on how we designed the async feature:
http://blogs.msdn.com/b/ericlippert/archive/tags/async/
As Eric Lippert pointed out, the first version won't compile; you have to remove the async keyword or you'll get a type error.
Here's a useful mental model regarding how the async and await keywords work with the return type:
Any value T returned by an async method is "wrapped" into a Task<T>.
The await keyword (which you can think of as an operator), when applied to a Task<T>, will "unwrap" it, resulting in a value of type T.
Now, that's an extreme simplification; what's actually happening is more complicated. E.g., this simplification skips over how await works with the current SynchronizationContext: in the second example, the method will attempt to return to the original context after the await completes, so you will observe different behavior if that context is busy.
But for the most part, the two examples are almost equivalent. The second one is less efficient due to the async state machine and resuming on the context.
I have an async/await intro that you may find helpful; in that post I try to explain async in a way that is not too complex but also not actually incorrect. :)
Eric's obviously the expert here and his advice is sound, but to answer your specific question:
In the first version, the async keyword on the method is irrelevant and your GetStringAsync method returns the same Task<string> awaitable that's returned by client.GetStringAsync.
In the second version, the async keyword on the method is required because you're using await in the method and the await keyword creates and returns a separate Task<string> awaitable that completes once the awaitable from client.GetStringAsync completes. When that occurs, the await then evaluates to the string that was asynchronously obtained by client.GetStringAsync which is returned as the result of your asynchronous method.
So to the caller of GetStringAsync, they're functionally the same, but the first version is cleaner.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does the async keyword exist
I have two methods. One is a normal method (MyMethod) and one is an async method (MyMethodAsync). I get a compilation error.
static string MyMethod()
{
var result = await MyMethodAsync(); // compile error here
return result;
}
async static Task<string> MyMethodAsync()
{
/** perform my logic here... **/
Thread.Sleep(1000);
return "yes";
}
The error message is
The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
I'm confused. When I use the await keyword, the calling thread will be suspended and wait for task completion. So once await is in use, the method is no longer an async method. Right?
Remark: I know I should put the logic in MyMethod and MyMethodAsync calls MyMethod to achieve what I want.
The entire point of the async keyword is to enable the await keyword.
I collected a number of "why do the keywords work that way?" questions on my blog. The question of "why can't async be inferred by the presence of await?" was answered conclusively by Eric Lippert on his blog. In short, two reasons: backwards compatibility and code readability.
For a huge amount of insight as to how async and await work internally, check out Jon Skeet's EduAsync blog series: msmvps.com/blogs/jon_skeet/archive/tags/Eduasync/default.aspx
This MSDN article also explains it: http://msdn.microsoft.com/en-us/library/vstudio/hh156513.aspx
Basically: a method modified by the async keyword contains at least one await expression or statement. The method runs synchronously until it reaches the first await expression, at which point it is suspended until the awaited task is complete. In the meantime, control is returned to the caller of the method. If the method does not contain an await expression or statement, then it executes synchronously.
Finally, this MSDN article: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx walks through a step-by-step example, about 1/3 of the way down the page: