参见英文答案 >
Fire-and-forget with async vs “old async delegate”4个
原谅我,如果这是一个愚蠢的问题.我一整天都在通过MSDN文档,他们的异步编码理念让我感到困惑.据了解,如果调用async方法,调用async方法的线程将不会被阻止.然而,异步在示例中始终配置等待,这似乎取消了异步,使得外部方法必须等待代码执行.应该不能调用异步方法,然后继续执行外部方法?
原谅我,如果这是一个愚蠢的问题.我一整天都在通过MSDN文档,他们的异步编码理念让我感到困惑.据了解,如果调用async方法,调用async方法的线程将不会被阻止.然而,异步在示例中始终配置等待,这似乎取消了异步,使得外部方法必须等待代码执行.应该不能调用异步方法,然后继续执行外部方法?
这是我遇到的情况,或多或少:
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关键字).
但是,为了执行bla bla,greaterProcess方法不需要等待(即等待)报告方法来完成.然而,VS告诉我,使用异步方法,我可以等待它,否则会同步发生,并阻止.这不会打败分开做的目的吗?
如何写这个,以使reportSomethingHappened不会阻止执行largeProcess? (这本质上令我感到困惑,因为我以为这是异步的一点)
解决方法
如果您调用异步方法,它将异步运行,无论您是否等待返回的任务.
等待不影响方法的执行方式,只影响调用者的处理方式.您可以调用异步方法,获取任务并立即等待(这是最简单的选项).这将使您能够编写看起来同步的代码,而异步运行,等待基本上将其余的代码注册为回调,只有在等待完成的任务完成后才能执行.这并不阻止传统的,因为没有线程被阻塞,但代码流将是顺序的:
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; } }
或者您可以完全删除等待.你应该意识到,这可能是危险的,因为任务可能是错误的,异常可以不被忽略,这就是为什么它不鼓励.有几种方法可以做到这一点,但它们并不简单.你可以使用Task.ContinueWith:
void LargerProcess() { if (condition) { ReportSomethingHappenedAsync().ContinueWith(task => { try { task.Wait(); } catch (Exception exception) { // handle exception } }) } // do other stuff }
或者为ASP.Net看看Fire and Forget on ASP.NET