在异步方法中最后一次异步调用需要等待吗?

时间:2013-11-29 13:57:49

标签: c# .net asynchronous

当async方法调用是我的异步方法中的最后一次调用时,我无法理解是否需要await语句。 E.g。

public async Task CallAsync(byte[] data)
{
    await Call1Async(data);
    Call2Async(data);
}

public async Task Call1Async(byte[] data)
{
   ...
}

public async Task Call2Async(byte[] data)
{
   ...
}

上面会编译,但会发出警告“考虑应用等待此方法”。但我认为应用等待该方法的最后一次调用会浪费资源。

与此同时,如果我使用return Call2Async(data);而非Call2Async(data);,警告就会消失。这表明在这种情况下实际上并不需要await

但这仅适用于具有返回值的方法(即Task<T>而不仅仅是Task)。我需要这个没有返回值的方法。有没有办法对价值回归方法做同样的事情?

即。我需要以某种方式将Task返回的Call2Async对象返回给CallAsync的来电者,我不能明确地使用return中的CallAsync语句作为我的方法没有回报价值。当然,我可以将它们全部调整为返回值(例如true),但这不是一个优雅的解决方案。

P.S。如果我在我的方法中只有异步调用,我就不会在方法签名中添加“async”,并且它可以工作(不需要'return'语句)。但是如果该方法包含多个异步调用,我需要'async'修饰符才能等待第一个调用'await Call1Async(data)'。并且添加“async”修饰符会使编译器需要“return”将Task对象返回给调用者(这仅适用于具有返回值的方法)。这就是我想要克服的。

2 个答案:

答案 0 :(得分:7)

在以下方法中:

public async Task CallAsync(byte[] data)
{
    await Call1Async(data);
    Call2Async(data);
}

开始Call2Async后,方法的控制权返回。也就是说,如果您到await CallAsync(data),它将在Call2Async结束之前完成。这可能不是你想要的。此方法仅在两个调用完成时完成:

public async Task CallAsync(byte[] data)
{
    await Call1Async(data);
    await Call2Async(data);
}

您可以看到这些示例输出的不同之处(我实现了两个异步调用,只需打印一个开始,延迟一秒,然后打印结束)。

void Main()
{
    Console.WriteLine("Main start");
    CallAsync(null).Wait();
    Console.WriteLine("Main end");
}

没有第二个await打印的方法:

Main start
Call1Async start
Call1Async end
Call2Async start
Main end
Call2Async end

第二个await

Main start
Call1Async start
Call1Async end
Call2Async start
Call2Async end
Main end

此实现也存在问题:

public Task CallAsync(byte[] data)
{
    Call1Async(data);
    return Call2Async(data);
}

它同时启动两个异步调用,但在Call2Async完成时返回控制,无论Call1Async是否完成。同样,这可能不是你想要的。

答案 1 :(得分:0)

async关键字表示该方法是异步的,并且其中包含await关键字。 我不明白为什么你有多个异步方法?

考虑以下示例:

async void MyMethod()
{
Task<object> result = MyWorkAsync();

MyIndependentOtherWork();

object res = await result;
}

调用MyWorkAsync就像创建一个“toto”线程来执行该方法(即Thread.Start(MyWorkAsyn))

await关键字就像从当前线程到线程“toto”进行连接,而不是获取“toto”的结果,并且同时让你的其他独立工作在当前线程上执行