异步如何处理封闭的UI?

时间:2015-01-23 11:43:14

标签: c# .net wpf multithreading task-parallel-library

我已经了解了如何在async C# tasks中使用C++/CX,但我正在寻找文档专家关于问题的答案这让我烦恼:

  

我启动了一个任务,该任务稍后将反映在启动它的UI (表单,页面等)中。但是,假设用户在实际完成之前将其关闭。或者在XAML框架/页面UI中返回/前进。

官方对此有何看法?我担心我的引用会指向可能崩溃的丢失对象。从我的测试...没有错误发生但我不确定。

PS 这可能是一个愚蠢的问题,但我是一个本地的C++线程'人,一个主要的困惑是将内容保留在范围内或复制/移动到线程上下文。

2 个答案:

答案 0 :(得分:2)

如果你执行Task.Run(() => this.someVariable)someVariable(以及this)将使实例保持活动状态,因为从lambda表达式派生的匿名方法引用该变量,尽管窗口可能会被关闭和处理,它仍然存在于记忆中。

最后,当任务结束,并且放弃所有引用时,将释放内存。这很可能是您没有收到异常的原因,而在访问已处置的对象时可能会遇到问题。

答案 1 :(得分:2)

确保您的任务不会尝试访问已处置对象的一种方法是为该任务提供CancellationToken。一旦你的XAML即将关闭,你可以挂钩其中一个OnClosing方法并触发取消:

private CancellationTokenSource = new CancellationTokenSource();

创建任务时,请传递令牌:

var task = Task.Run(() => 
                   {
                         cts.ThrowIfCancellationRequested();
                   }, cts.Token);

当你即将关闭时,发出信号:

protected override void OnClosing() 
{
     cts.Cancel();
}

这样,您可以确保仅在未取消任务时访问UI元素,并避免访问已处置的对象。