async 是如何处理 closed UI 的?
How does async deal with closed UI?
我已经在 C#
中学习了如何使用 async
(C++/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 元素,并避免访问已处置的对象。
我已经在 C#
中学习了如何使用 async
(C++/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 元素,并避免访问已处置的对象。