async 是如何处理 closed UI 的?

How does async deal with closed UI?

我已经在 C# 中学习了如何使用 asyncC++/CX 中的 tasks),但我正在寻找文档专家关于以下内容的答案一个困扰我的问题:

I launch a task that will later reflect in the UI (form, page, etc...) that launched it. But let's say the user closes it before actually completing. Or goes back/forward in a XAML frame/page UI.

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

PS这可能是一个愚蠢的问题,但我是本地人 C++ threads 的人和一个主要的痴迷者将内容保持在范围内或 copying/moving 预先线程上下文。

如果您这样做 Task.Run(() => this.someVariable),那 someVariable(以及 this 也会)将使实例保持活动状态,因为从 lambda 表达式派生的匿名方法引用了该变量,尽管windows 可能会被关闭和处置,它仍然存在于内存中。

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

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

private CancellationTokenSource = new CancellationTokenSource();

创建任务时,传递令牌:

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

当您即将关闭时,发出令牌信号:

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

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