Ste*_*fan 0 .net c# async-await
想象一下,我有这个async方法:
public async Task Foo(object fooObj)
{
//do foo's stuff.
//maybe set a fooable static global variable
//or write some data to fooObj
}
Run Code Online (Sandbox Code Playgroud)
并称之为:
public async void FooCaller()
{
await Foo(new dummyObject)
}
Run Code Online (Sandbox Code Playgroud)
好吧,所以:第一个代码块返回一个Task,但实际上并没有返回任何地方.
我可以想象async关键字case 有一些编译器异常,否则需要返回值.
但如果是这种情况,返回值如何初始化?(好吧,我可以自己查一下).
更重要:
使用这种模式时是否有任何陷阱?(例如:访问fooObj,延迟执行时间......等)
好吧,所以:第一个代码块返回一个Task,但它实际上并没有返回任何地方.
确实.您可以将其视为Task<void>- 如果这是有效的.它用于指示异步方法何时完成.
基本上,任何非void异步方法都会包装您在任务中返回的任何内容.例如:
async Task<string> FooAsync()
{
// Do some async operations
return "foo";
}
Run Code Online (Sandbox Code Playgroud)
请注意,return语句中表达式的类型是string,但方法的声明返回类型是Task<string>.编译器完成所有工作以将异步操作包装在一个合适的操作中Task,该方法在方法完成或抛出异常时完成.(在这种情况下,返回的Task状态为"故障".)
这是必需的原因是对异步方法的调用通常在方法完成之前返回.将方法调用视为"请开始做某事" - 它将启动并返回,但您想知道"某事"何时完成,以及结果是什么.
一个await表达式执行相反的解包 -它仅将通过该方法继续在等待操作完成,和解开的值(例如,使用Task.Result).但它不会阻塞,而是会立即返回.这就是组合如何与等待其他异步方法的结果的异步方法很好地协作.
一旦你的窍门string,以Task<string>包装和等价的,如果你展开await了任务,应该很容易看到类比Task和void.所以就像这对void方法有效:
void Foo()
{
// Do some actions.
...
// No need for a return statement
}
Run Code Online (Sandbox Code Playgroud)
等效方法适用于某种async Task方法:
async Task Foo()
{
// Do some actions (presumably using await)
...
// No need for a return statement
}
Run Code Online (Sandbox Code Playgroud)
您可以在方法中使用return语句(没有值)async Task:
async Task Foo()
{
if (weDontNeedToDoAnything)
{
return; // This is fine
}
// Do some actions (presumably using await)
...
// No need for a return statement
}
Run Code Online (Sandbox Code Playgroud)