我整天都在浏览MSDN文档,他们的异步编码理念使我感到困惑。据我了解,调用async方法的线程不会被阻塞。但是,在示例中,异步总是与await配对,这似乎抵消了异步性,从而使外部方法必须等待代码无论如何执行。我是否应该能够调用异步方法然后继续执行外部方法?
这或多或少是我一直遇到的情况:
void reportSomethingHappened(info)
- Collect info
- HTTP POST info to logging server (ie. mixpanel, sentry)
这是一个调用方法:
void largerProcess
if (whatever)
reportSomethingHappened();
bla;
bla;
据我了解,由于POST请求可以异步完成,因此我应该能够使reportSomethingHappened()成为异步方法(通过AFAIK,等待webrequest,并添加async关键字)。
但是,largeProcess方法不需要等待(即等待)报告方法完成即可执行bla bla bla。但是,VS告诉我,使用异步方法,我可以等待它,也可以同步发生并阻塞。这是否会破坏单独进行的目的?
如何编写此代码,以便reportSomethingHappened不会阻止LargeProcess的执行?(这天生使我感到困惑,因为我一直认为那是异步的关键)
如果您调用异步方法,则无论您是否await
返回任务,它都会异步运行。
await
不会影响该方法的执行方式,只会影响您作为调用方的处理方式。您可以调用async方法,获取任务并立即等待(这是最简单的选项)。这样一来,您就可以编写看似同步但异步运行await
的代码,因为该代码基本上将其余代码注册为回调,仅在等待任务完成后才执行。在传统上这不会阻塞,因为没有线程被阻塞,但是代码流将是顺序的:
async Task LargerProcessAsync()
{
if (condition)
{
await ReportSomethingHappenedAsync();
}
// do other stuff
}
但是,您不一定需要这样做。您可以将任务取回,做其他事情,然后再做await
:
async Task LargerProcessAsync()
{
Task task = null;
if (condition)
{
task = ReportSomethingHappenedAsync();
}
// do other stuff
if (task != null)
{
await task;
}
}
或者,您可以简单地将其await
完全删除。您应该意识到,这样做可能很危险,因为任务可能会出错,并且异常可能会被忽略,这就是为什么不鼓励这样做的原因。有几种方法可以做到这一点,但这并不简单。您可以使用Task.ContinueWith
:
void LargerProcess()
{
if (condition)
{
ReportSomethingHappenedAsync().ContinueWith(task =>
{
try
{
task.Wait();
}
catch (Exception exception)
{
// handle exception
}
})
}
// do other stuff
}
或对于ASP.Net,请在ASP.NET上查看Fire and Forget
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句