异步任务的 return 值是多少?
What is the return value of async Task?
假设我有这个 async
方法:
public async Task Foo(object fooObj)
{
//do foo's stuff.
//maybe set a fooable static global variable
//or write some data to fooObj
}
并这样称呼它:
public async void FooCaller()
{
await Foo(new dummyObject)
}
好的,所以:第一个代码块 return 是一个 Task
,但它实际上并没有在任何地方被 return 编辑。
我可以想象 async
关键字大小写有一些编译器异常,否则需要 return 值。
但是如果是这样的话,return这个值是怎么初始化的呢? (好的,我可以自己检查)。
更重要的是:
使用这个模式有什么陷阱吗? (例如:访问 fooObj
、延迟执行时间等)
Ok, so: this first code block returns a Task, but it isn't actually returned anywhere.
确实如此。你可以把它想象成 Task<void>
- 如果它有效的话。它用于指示异步方法何时完成。
基本上,任何非 void 异步方法都会包装您 return 在任务中的任何内容。例如:
async Task<string> FooAsync()
{
// Do some async operations
return "foo";
}
注意return
语句中表达式的类型是string
,但是方法声明的return类型是Task<string>
。编译器完成所有工作以将异步操作包装在合适的 Task
中,该操作在方法完成或抛出异常时完成。 (在这种情况下,returned Task
具有 "faulted" 状态。)
之所以需要这样做,是因为在方法 完成 之前,对异步方法的调用通常 returns。将方法调用视为 "Please start doing something" - 它将 启动 它和 return,但您想知道 "something" 何时完成,并且结果是什么。
await
表达式执行相反的 unwrapping - 它只会在等待的操作完成时继续执行该方法,并解包值(例如使用 Task.Result
).但是它不会阻塞,而是立即使该方法 return。这就是组合与等待其他异步方法结果的异步方法一起工作的方式。
一旦掌握了 string
到 Task<string>
包装的窍门,以及 await
任务的等效展开,应该很容易看出与 Task
和 void
。因此,正如这对 void
方法有效一样:
void Foo()
{
// Do some actions.
...
// No need for a return statement
}
async Task
方法等价:
async Task Foo()
{
// Do some actions (presumably using await)
...
// No need for a return statement
}
您可以在async Task
方法中有一个return
语句(没有值):
async Task Foo()
{
if (weDontNeedToDoAnything)
{
return; // This is fine
}
// Do some actions (presumably using await)
...
// No need for a return statement
}
假设我有这个 async
方法:
public async Task Foo(object fooObj)
{
//do foo's stuff.
//maybe set a fooable static global variable
//or write some data to fooObj
}
并这样称呼它:
public async void FooCaller()
{
await Foo(new dummyObject)
}
好的,所以:第一个代码块 return 是一个 Task
,但它实际上并没有在任何地方被 return 编辑。
我可以想象 async
关键字大小写有一些编译器异常,否则需要 return 值。
但是如果是这样的话,return这个值是怎么初始化的呢? (好的,我可以自己检查)。
更重要的是:
使用这个模式有什么陷阱吗? (例如:访问 fooObj
、延迟执行时间等)
Ok, so: this first code block returns a Task, but it isn't actually returned anywhere.
确实如此。你可以把它想象成 Task<void>
- 如果它有效的话。它用于指示异步方法何时完成。
基本上,任何非 void 异步方法都会包装您 return 在任务中的任何内容。例如:
async Task<string> FooAsync()
{
// Do some async operations
return "foo";
}
注意return
语句中表达式的类型是string
,但是方法声明的return类型是Task<string>
。编译器完成所有工作以将异步操作包装在合适的 Task
中,该操作在方法完成或抛出异常时完成。 (在这种情况下,returned Task
具有 "faulted" 状态。)
之所以需要这样做,是因为在方法 完成 之前,对异步方法的调用通常 returns。将方法调用视为 "Please start doing something" - 它将 启动 它和 return,但您想知道 "something" 何时完成,并且结果是什么。
await
表达式执行相反的 unwrapping - 它只会在等待的操作完成时继续执行该方法,并解包值(例如使用 Task.Result
).但是它不会阻塞,而是立即使该方法 return。这就是组合与等待其他异步方法结果的异步方法一起工作的方式。
一旦掌握了 string
到 Task<string>
包装的窍门,以及 await
任务的等效展开,应该很容易看出与 Task
和 void
。因此,正如这对 void
方法有效一样:
void Foo()
{
// Do some actions.
...
// No need for a return statement
}
async Task
方法等价:
async Task Foo()
{
// Do some actions (presumably using await)
...
// No need for a return statement
}
您可以在async Task
方法中有一个return
语句(没有值):
async Task Foo()
{
if (weDontNeedToDoAnything)
{
return; // This is fine
}
// Do some actions (presumably using await)
...
// No need for a return statement
}