所以我有这个WrapperFunction试图使FunctionReturningVoid被异步调用:
public async Task WrapperFunction()
{
this.FunctionReturningVoid("aParameter");
}
Run Code Online (Sandbox Code Playgroud)
这是什么都不返回的函数。在代码的某些部分(此处未详细介绍),它被称为SYNChronously,但在CallerFunction()中,我们希望它以ASYNChronously运行。
public void FunctionReturningVoid(string myString)
{
Console.Write(myString);
}
Run Code Online (Sandbox Code Playgroud)
这是已实现异步的函数,需要WrapperFunction进行操作而不阻塞otherStuff()。
public async Task CallerFunction()
{
await WrapperFunction():
int regular = otherStuff();
...
}
Run Code Online (Sandbox Code Playgroud)
IDE向我警告WrapperFunction没有使用await:
这种异步方法缺少“等待”运算符,将同步运行。考虑使用“ await”运算符来等待非阻塞API调用,或者使用“ await Task.Run(...)”来在后台线程上执行CPU绑定的工作。
问题:如何在WrapperFunction中使用异步而不使用await?如果我使用await,它告诉我不能等待void。
区分异步与并行很重要。
异步意味着在等待某些事情发生时不阻塞当前线程。这使当前线程可以在等待时执行其他操作。
并行意味着同时做一件事。这需要为每个任务使用单独的线程。
您不能FunctionReturningVoid异步调用,因为它不是异步方法。在您的示例中,Console.WriteLine()将以阻塞线程直到完成的方式编写代码。您无法更改。但我知道这只是您针对此问题的示例。如果您的实际方法正在执行某种I / O操作,例如网络请求或写入文件,则可以将其重写为使用异步方法。但是,如果它正在执行大量的CPU工作,或者您无法重写它,那么您就被它保持同步-它会在运行时阻塞当前线程。
但是,您可以FunctionReturningVoid并行运行(在另一个线程上)并异步等待它(这样它就不会阻塞当前线程)。如果这是一个桌面应用程序,这将是明智的选择–您不想在UI运行时锁定它。
为此,您可以使用Task.Run,它将在另一个线程上运行代码,并返回一个Task您可以用来在完成时知道的代码。这意味着您WrapperFunction将如下所示:
public Task WrapperFunction()
{
return Task.Run(() => this.FunctionReturningVoid("aParameter"));
}
Run Code Online (Sandbox Code Playgroud)
观点:注意,我删除了async关键字。这是没有必要的,因为您可以将传递Task给调用方法。这里有更多关于此的信息。
Microsoft有一些写得很好的关于异步编程和异步编程的文章,值得一读。