为什么我必须使用 await 来异步运行方法.如果我不想在继续之前等待方法完成怎么办? [英] Why do I have to use await for a method to run asynchronously. What if I don't want to wait for the method to finish before continuing?

查看:21
本文介绍了为什么我必须使用 await 来异步运行方法.如果我不想在继续之前等待方法完成怎么办?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一整天都在翻阅 MSDN 文档,他们的异步编码哲学让我很困惑.据我了解,如果调用异步方法,调用异步方法的线程不会被阻塞.然而,在示例中 async 总是与 await 配对,这似乎否定了异步性,使得外部方法无论如何都必须等待代码执行.我不应该能够调用异步方法然后继续执行外部方法吗?

I've been pouring through MSDN docs all day, and their philosophy of asynchronous coding is confusing me. As I understand it, the thread that calls the async method will not be blocked if the async method is called. Yet, async is always paired in examples with await, which appears to negate the async-ness, making it so that the outer method DOES have to wait for the code to execute anyway. Shouldn't I be able to call an async method and then continue with the execution of the outer method?

这就是我或多或少遇到的场景:

This is the scenario I've been encountering, more or less:

void reportSomethingHappened(info)
    - Collect info
    - HTTP POST info to logging server (ie. mixpanel, sentry)

这里是一个调用方法:

void largerProcess
    if (whatever)
        reportSomethingHappened();
    bla;
    bla;

据我所知,由于 POST 请求可以异步完成,我应该能够将 reportSomethingHappened() 变成异步方法(通过 AFAIK,等待 web 请求,并添加 async 关键字).

As far as I understand, since POST requests can be done asynchronously, I should be able to make reportSomethingHappened() into an async method (by, AFAIK, await-ing the webrequest, and adding the async keyword).

但是largerProcess 方法不需要等待(即等待)报告方法完成才能执行bla bla.然而,VS 告诉我,使用异步方法,我可以等待它,或者它会同步发生并阻塞.这不会违背分开做的目的吗?

But the largerProcess method doesn't need to wait for (ie. await) the reporting method to finish in order to execute bla bla. Yet, VS tells me that with an async method I can either await it, or it will happen synchronously, and block. Doesn't that defeat the purpose of doing it separately?

我该如何编写才能使reportSomethingHappened 不会阻止largerProcess 的执行?(这本质上让我感到困惑,因为我一直认为这就是异步的重点)

How do I write this so that reportSomethingHappened doesn't block execution of largerProcess? (Which is inherently confusing me, because I thought that was the point of async all along)

推荐答案

如果你调用一个异步方法,无论你是否await返回的任务,它都会异步运行.

If you call an asynchronous method it will run asynchronously whether you await the returned task or not.

await 不会影响方法的执行方式,只会影响您作为调用者的处理方式.您可以调用异步方法,获取任务并立即等待(这是最简单的选择).这将使您能够编写看起来同步但异步运行的代码,因为 await 基本上将其后的其余代码注册为仅在等待的任务完成后才执行的回调完全的.这不会在传统中阻塞,因为没有线程被阻塞,但是代码流将是顺序的:

await doesn't affect how the method executes, only how you as the caller deals with it. You can call the async method, get the task and await it right away (which is the simplest option). That will enable you to write code that looks synchronous but runs asynchronously as await basically registers the rest of the code after it as a callback to be executed only after the awaited task is completed. This doesn't block in the traditional since as no thread is blocked, but the code flow will be sequential:

async Task LargerProcessAsync()
{
    if (condition)
    {
        await ReportSomethingHappenedAsync();
    }

    // do other stuff
}

但是,您并非绝对需要这样做.你可以拿回任务,做其他事情,然后await它:

However, you don't absolutely need to do that. You can get the task back, do other stuff and only then await it:

async Task LargerProcessAsync()
{
    Task task = null;
    if (condition)
    {
        task = ReportSomethingHappenedAsync();
    }

    // do other stuff

    if (task != null)
    {
        await task;
    }
}

或者您可以简单地完全删除await.您应该意识到这可能是危险的,因为任务可能会出错并且异常可能未被观察到,这就是不鼓励这样做的原因.有几种方法可以正确地做到这一点,但它们并不简单.您可以使用 Task.ContinueWith:

Or you can simply remove the await completely. You should realize though that this can be dangerous as the task can be faulted and the exception can go unobserved and that's why it's discouraged. There are several ways to do this right, but they aren't simple. You can use Task.ContinueWith:

void LargerProcess()
{
    if (condition)
    {
        ReportSomethingHappenedAsync().ContinueWith(task => 
        {
            try
            {
                task.Wait();
            }
            catch (Exception exception)
            {
                // handle exception
            }
        })
    }

    // do other stuff
}

或者对于 ASP.Net,请查看 在 ASP 上开火即忘.网络

Or for ASP.Net look at Fire and Forget on ASP.NET

这篇关于为什么我必须使用 await 来异步运行方法.如果我不想在继续之前等待方法完成怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆