C# 为什么我必须使用wait来异步运行一个方法。如果我没有';您不想等待方法完成后再继续吗?
我整天都在浏览MSDN文档,他们的异步编码哲学让我困惑。据我所知,如果调用异步方法,调用异步方法的线程将不会被阻塞。然而,在示例中,async总是与wait成对出现,这似乎否定了异步性,使得外部方法无论如何都必须等待代码执行。我不应该调用一个异步方法,然后继续执行外部方法吗 这就是我遇到的情况,或多或少:C# 为什么我必须使用wait来异步运行一个方法。如果我没有';您不想等待方法完成后再继续吗?,c#,.net,asynchronous,async-await,.net-4.5,C#,.net,Asynchronous,Async Await,.net 4.5,我整天都在浏览MSDN文档,他们的异步编码哲学让我困惑。据我所知,如果调用异步方法,调用异步方法的线程将不会被阻塞。然而,在示例中,async总是与wait成对出现,这似乎否定了异步性,使得外部方法无论如何都必须等待代码执行。我不应该调用一个异步方法,然后继续执行外部方法吗 这就是我遇到的情况,或多或少: void reportSomethingHappened(info) - Collect info - HTTP POST info to logging server (ie
void reportSomethingHappened(info)
- Collect info
- HTTP POST info to logging server (ie. mixpanel, sentry)
下面是一个调用方法:
void largerProcess
if (whatever)
reportSomethingHappened();
bla;
bla;
据我所知,因为POST请求可以异步完成,所以我应该能够将reportSomethingOccessed()转换为一个异步方法(通过,AFAIK,等待webrequest,并添加async关键字)
但是largerProcess方法不需要等待(即等待)报告方法完成才能执行bla bla。然而,VS告诉我,使用异步方法,我可以等待它,或者它将同步发生,然后阻塞。这不是违背了分开做的目的吗
我如何编写此报告,以便ReportSomethingOccessed不会阻止更大进程的执行?(这让我很困惑,因为我一直认为这就是异步的要点)如果调用异步方法,无论是否等待返回的任务,它都将异步运行
await
不影响方法的执行方式,只影响调用方处理方法的方式。您可以调用async方法,获取任务并立即等待它(这是最简单的选项)。这将使您能够编写看起来同步但异步运行的代码,因为await
基本上是将它之后的其余代码注册为回调,仅在等待的任务完成后执行。这在传统模式中不会阻塞,因为没有线程被阻塞,但代码流将是顺序的:
async Task LargerProcessAsync()
{
if (condition)
{
await ReportSomethingHappenedAsync();
}
// do other stuff
}
然而,你并不一定要这么做。你可以拿回任务,做其他事情,然后等待它:
async Task LargerProcessAsync()
{
Task task = null;
if (condition)
{
task = ReportSomethingHappenedAsync();
}
// do other stuff
if (task != null)
{
await task;
}
}
或者,只需完全删除wait
。不过,您应该意识到,这可能是危险的,因为任务可能会出错,异常可能会被忽略,这就是为什么不鼓励这样做。有几种方法可以做到这一点,但它们并不简单。您可以使用任务。继续使用:
void LargerProcess()
{
if (condition)
{
ReportSomethingHappenedAsync().ContinueWith(task =>
{
try
{
task.Wait();
}
catch (Exception exception)
{
// handle exception
}
})
}
// do other stuff
}
或者,对于ASP.Net,查看wait异步等待,它不会在传统意义上阻塞。你不必等待结果,但大部分时间你都想等待。一个常见的误解是async
使事情变得异步。事实并非如此。正是wait
使事情变得异步。(他们试图为这些关键词选择正确的名称,但这仍然让人们感到困惑)@CharlesMager为什么它是异步的,如果bla和bla在报告完成之前不会执行?@Dennis_E甚至wait
也不会使任何东西异步。它使使用已经异步的东西变得更容易,特别是,它使异步操作完成后异步执行某些事情变得更容易。您需要已经有了一个异步操作才能等待它,所以它不是创建异步的await
。@i3arnon因此,正如您和其他人(包括Visual Studio本身)所指出的,后一种情况,在异步运行时不等待它,是危险和不好的做法。那么,在你不想等待任务的情况下,处理这种情况的正确方法是什么?什么是最好的实践?@ the FifStHER你可以使用<代码>异步空洞< /代码>或<代码>任务。继续使用< /COD>(添加到答案)或类似于ASP.NET的吊火。@ THEFIPSHOTH但是,你应该考虑为什么你不想等待(异步)开始操作。