C# 未等待时配置等待
我有一个C# 未等待时配置等待,c#,asp.net,async-await,synchronizationcontext,azure-webjobs,C#,Asp.net,Async Await,Synchronizationcontext,Azure Webjobs,我有一个async方法,我用它来减轻几秒钟的工作量,忘记工作,以免减慢页面加载速度。这项工作需要一些一般的设置和整理;如果抛出,我希望(fast)设置同步抛出,但我不想强制整理在ASP上下文中运行,因此我在等待的位上使用ConfigureAwait: public Task FireAndForget() { DoSetup(); return FireAndForgetAfterSetup(); } private async Task FireAndForgetAfterS
async
方法,我用它来减轻几秒钟的工作量,忘记工作,以免减慢页面加载速度。这项工作需要一些一般的设置和整理;如果抛出,我希望(fast)设置同步抛出,但我不想强制整理在ASP上下文中运行,因此我在等待的位上使用ConfigureAwait
:
public Task FireAndForget()
{
DoSetup();
return FireAndForgetAfterSetup();
}
private async Task FireAndForgetAfterSetup()
{
await AFewSecondsWorthOfWork().ConfigureAwait(false);
DoTidyUp();
}
protected void btn_Click(object sender, EventArgs e)
{
FireAndForget();
}
这似乎很奇怪,因为
不应该真正关心它是否是从ASP上下文调用的,那么为什么它必须是调用FireAndForgetAfterSetup
的那一个呢ConfigureAwait
- 如果我改变主意,决定
应该等待btn_Click
完成,那么它是否已经抛弃了ASP上下文(?)FireAndForget
如果我有误解,有人能给我解释一下吗?ASP.NET同步上下文不允许在请求中启动并忘记工作项。运行时会主动监视这些事情,并尝试生成异常,因为这些代码模式会导致空引用、死锁、AV和其他不好的情况
如果你真的需要开火,忘记在ASP.NET工作,考虑使用。它与ASP.NET扩展点集成,这些扩展点旨在实现这一点。因此,它不会阻止活动请求,但请记住Stephen的警告:它根本不能保证被执行。如果需要保证执行,请考虑像服务总线这样的可靠性机制。 < P> ASP.NET同步上下文不允许在请求内开火和忘记工作项。运行时会主动监视这些事情,并尝试生成异常,因为这些代码模式会导致空引用、死锁、AV和其他不好的情况
如果你真的需要开火,忘记在ASP.NET工作,考虑使用。它与ASP.NET扩展点集成,这些扩展点旨在实现这一点。因此,它不会阻止活动请求,但请记住Stephen的警告:它根本不能保证被执行。如果需要保证执行,请考虑一个可靠性机制,如Service BUS。 < P>如果您的场景是如何在加载期间执行一些(相对)长时间运行的任务,那么ASP.NET通过该方法允许该场景。Scott Hansleman介绍了如何在中使用它 本质上,您创建了一个异步方法,该方法返回任务和调用:
RegisterAsyncTask(new PageAsyncTask(MyAsyncMethod));
然后调用以开始执行所有已注册的任务
Scott Hanselman(当然)很好地描述了为什么使用事件处理程序、任务或后台线程是个坏主意
这在“异步页面事件”部分的“”中也有描述。如果您的场景是如何在加载期间执行一些(相对)长时间运行的任务,ASP.NET允许通过该方法执行此场景。Scott Hansleman介绍了如何在中使用它 本质上,您创建了一个异步方法,该方法返回任务和调用:
RegisterAsyncTask(new PageAsyncTask(MyAsyncMethod));
然后调用以开始执行所有已注册的任务
Scott Hanselman(当然)很好地描述了为什么使用事件处理程序、任务或后台线程是个坏主意
在“异步页面事件”部分的“”中也描述了这一点,我不确定他为什么没有发布它,但我的两个问题在中得到了回答: 本例中需要注意的重要一点是,异步方法调用的每个“级别”都有自己的上下文。DownloadFileButton\单击在UI上下文中启动,并调用DownloadFileAsync。DownloadFileAsync也在UI上下文中启动,但随后通过调用ConfigureAwait(false)退出其上下文。DownloadFileAsync的其余部分在线程池上下文中运行。但是,当DownloadFileAsync完成并单击DownloadFileButton_恢复时,它会在UI上下文中恢复 一个好的经验法则是使用ConfigureAwait(false),除非您知道确实需要上下文
- 在回答我的第一个要点时,是的,在库方法中使用
是可以的(鼓励!),因为ConfigureAwait(false)
- 。。。在回答我的第二个要点时,即使库
方法丢弃了UI上下文,调用方法仍然有自己的副本。因此,调用方法可以等待库方法,并在UI上下文中恢复。。。但当这种情况发生时,它将陷入僵局async
- 在回答我的第一个要点时,是的,在库方法中使用
是可以的(鼓励!),因为ConfigureAwait(false)
- 。。。在回答我的第二个要点时,即使库
方法丢弃了UI上下文,调用方法仍然有自己的副本。因此,调用方法可以等待库方法,并在UI上下文中恢复。。。但当这种情况发生时,它将陷入僵局async