Say I have method such as this:
private async Task SomeMethod()
{
await DoSomethingAsync();
await DoSomethingElseAsync();
return;
}
Given that DoSomethingElseAsync
returns a Task
it would seem like you should be able to do this:
private async Task SomeMethod()
{
await DoSomethingAsync();
return DoSomethingElseAsync();
}
but the compiler complains about this:
Since '
SomeMethod
' is an async method that returns 'Task
', a return keyword must not be followed by an object expression. Did you intend to return 'Task<T>
'?
Why is that?
Its pretty much like how yield return
and return
works. for an iterator you have either of these methods
public IEnumerable<int> SomeIterator()
{
for(int I = 0; I < 10; I++) yield return I;
}
public IEnumerable<int> SomeIterator()
{
return Enumerable.Range(0, 10); // return result of another iterator.
}
but you cant have both. it doesn't work, because an iterator is either converted to a class by compiler to handle lazy iteration with yield
, or its just like other normal methods that returns something else.
public IEnumerable<int> SomeIterator() // not valid
{
for(int I = 0; I < 10; I++) yield return I;
return Enumerable.Range(0, 10);
}
The story is same about return
and async/await
. for method that has return type of Task
you either return Task
or use async/await
.
for Task<T>
if you use await you must return T
but you can not return Task<T>
because the method is compiled into state machine, then method must return T
. (for Task
method is void)
if you don't use async/await
method will be exactly like other normal methods.
When you use await
- control flow might leave current method and return back to the caller. Suppose DoSomethingAsync
is some long running operation. You call SomeMethod
. DoSomethingAsync
task is started but then you cannot wait for it to complete inside that method - otherwise nothing will be "async". So control flow leaves Method
and should provide a return value to the caller. Return value is a task which completes when whole SomeMethod
is completed. It can complete with or without result ( Task
or Task<T>
return value). For that reason what you return after await
could not be return type of SomeMethod
- it can only be result type T
(if SomeMethod
returns Task) or just simple return
to indicate completion of SomeMethod
if it returns simple Task
.
In a normal method, return
means "return this value, if any, from the method". In an async
method, the meaning of return
is changed to "set the result of the returned Task
to this value, if any".
But you can't combine the two: in an async Task
method, you can't directly return
a Task
. One reason for this is that if you await
ed, the method actually already returned a Task
and it can't return another one.
When it comes to returning, async Task
method behaves like a void
method, in that it only allows return;
, but never return value;
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.