异步任务的返回值是多少?

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,延迟执行时间......等)

Jon*_*eet 8

好吧,所以:第一个代码块返回一个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了任务,应该很容易看到类比Taskvoid.所以就像这对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)