C# 为什么我必须使用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

我整天都在浏览MSDN文档,他们的异步编码哲学让我困惑。据我所知,如果调用异步方法,调用异步方法的线程将不会被阻塞。然而,在示例中,async总是与wait成对出现,这似乎否定了异步性,使得外部方法无论如何都必须等待代码执行。我不应该调用一个异步方法,然后继续执行外部方法吗

这就是我遇到的情况,或多或少:

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但是,你应该考虑为什么你不想等待(异步)开始操作。