我有一个async方法,用于卸载几秒钟的触发和遗忘工作,以避免减缓页面加载速度。这项工作需要一些一般性设置和整理;如果抛出,我希望(快速)设置同步抛出,但我不想强制在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();
}这看起来很奇怪,因为
FireAndForgetAfterSetup不应该真正关心它是否是从ASP上下文中调用的,那么为什么它必须是调用ConfigureAwait的btn_Click应该等待FireAndForget完成,它是否已经丢弃了ASP上下文(?)有人能给我解释一下如果我误会了吗?
发布于 2014-03-18 16:08:12
ASP.NET同步上下文不允许从请求中启动触发和忘记工作项。运行时会主动监视这些事情,并尝试生成异常,因为这些代码模式会导致空引用、死锁、AVs和其他恶意。
如果您绝对需要在ASP.NET中开始工作而忘记工作,请考虑使用WebBackgrounder。它与ASP.NET扩展点集成在一起,这些扩展点就是为此而设计的。因此,它不会阻止主动请求,但请记住Stephen的警告:它根本不一定会被执行。如果需要有保证的执行,请考虑像服务总线这样的可靠性机制。
发布于 2014-03-18 16:53:03
如果您的场景是如何在加载期间执行一些(相对地)长时间运行的任务,则ASP.NET允许通过Page.RegisterAsyncTask方法执行此场景。Scott描述了如何在在ASP.NET 4.5中使用异步方法的魔力加上一个重要的问题中使用它
本质上,您创建了一个异步方法,该方法返回任务并调用:
RegisterAsyncTask(new PageAsyncTask(MyAsyncMethod));然后调用Page.ExecuteRegisteredAsyncTasks开始执行所有已注册的任务。
Scott很好地描述了为什么使用事件处理程序、任务或后台线程是个坏主意。
这在“异步页面事件”部分的"在ASP.NET中不应该做什么,应该做什么“中也有描述。
发布于 2014-03-18 17:23:29
我不知道他为什么不发,但我的两个问题在这篇博文是斯蒂芬·克利里写的上得到了答案
在这个例子中需要注意的是,每个异步方法调用的“级别”都有它自己的上下文。DownloadFileButton_Click从UI上下文中开始,称为DownloadFileAsync。DownloadFileAsync也是在UI上下文中启动的,但随后通过调用ConfigureAwait(false)脱离了上下文。DownloadFileAsync的其余部分在线程池上下文中运行。但是,当DownloadFileAsync完成并且DownloadFileButton_Click恢复时,它确实会在UI上下文中恢复。 一个好的经验法则是使用ConfigureAwait(false),除非您知道您确实需要上下文。
ConfigureAwait(false),因为.async方法丢弃了UI上下文,调用方法仍然有它自己的副本。因此,调用方法可以在UI上下文中await库方法并恢复.但一旦发生这种情况就会陷入僵局。https://stackoverflow.com/questions/22483128
复制相似问题