如果相关联的UI被释放,那么C#中的异步可调用代码会发生什么



假设我有一个WPF对话框,其中有异步事件处理程序,等待一些需要很长时间的调用。然后,用户在等待返回之前关闭对话框(代码将其处理)。我想那会造成车祸。有没有规定的方法可以使用C#5中的新async/await关键字和.NET 4.5中的新TaskAsync方法来处理这种情况?

async/await应该可以正常工作。

每个WPF窗口都会创建自己的SynchronizationContext——至少现在是这样(这是一个实现细节)。但这些只是普通Dispatcher的简单包装。

因此,TaskAwaiter最终会为被破坏的窗口捕获SynchronizationContext,但这并不重要,因为Dispatcher仍然存在。

现在,您的代码所做的是另一回事。例如,如果在这种情况下有一个async事件处理程序,它必须能够处理已处理实例上的恢复。

Adam和leppie都有很好的评论:要么阻止用户关闭对话框,要么取消任务(并确保在实际关闭对话框之前取消任务)。另一个好的选择是启动Task,然后将其添加到正在进行的操作的共享集合中。所有这些选项都可以防止async事件处理程序在已释放的实例上运行的不良情况。

我认为这取决于具体情况。如果您在Dispose()d对象的async方法中有代码,它可以很好地继续,因为Dispose()对框架没有任何意义。当然,如果该方法调用某个将抛出ObjectDisposedException(或其他异常)的方法,则会停止异步操作(除非捕捉到异常)。但这并不是自动发生的。

最新更新