提问人:Luka 提问时间:11/18/2023 更新时间:11/18/2023 访问量:47
WPF 未释放视图模型
WPF not disposing viewmodel
问:
我遇到了关于 wpf 的内存泄漏问题...... 因此,我有一个未被释放的视图模型。 我将问题范围缩小到调用数据库并更新 viewModel 上的字段的方法。
它是这样的:
public async Task RefreshAsync2(CancellationToken token = default)
{
var data = await Mediator.Send(new GetDataQuery());
if (data != null)
{
Dispatcher.CurrentDispatcher.Invoke(() => {
ViewModelInfo = data;
});
}
}
在此方法中,问题出在 Dispatcher.CurrentDispatcher.Invoke 中,它使用匿名 (lambda) 方法来捕获“this”。
我必须使用Dispatcher,因为可以从另一个线程调用此刷新方法,即。计时器。
如何摆脱这个?
答:
1赞
Clemens
11/18/2023
#1
无论如何,使用是错误的。它将为尚无 Dispatcher 的(后台)线程创建一个新的 Dispatcher。看这里:Dispatcher.CurrentDispatcher
获取当前正在执行的线程的 Dispatcher,并创建一个新的 Dispatcher(如果尚未与该线程关联)。
那不是你想要的。使用或以某种方式将 UI Dispatcher 作为参数传递给视图模型。Application.Current.Dispatcher
但是,假设您调用
await RefreshAsync2();
在UI线程中,您根本不需要Dispatcher调用。此代码应足够:
public async Task RefreshAsync2(CancellationToken token = default)
{
var data = await Mediator.Send(new GetDataQuery());
if (data != null)
{
ViewModelInfo = data;
}
}
评论
0赞
Luka
11/18/2023
但正如我在问题中所说,这个方法可以从另一个线程调用,即。另一个任务、后台作业或计时器。这就是我使用Dispatcher的原因。
0赞
Clemens
11/18/2023
那么使用还是不对的。Dispatcher.CurrentDispatcher
1赞
Clemens
11/18/2023
对于计时器,请使用 DispatcherTimer。
0赞
Luka
11/18/2023
那么其他后台工作(任务)呢?
1赞
Clemens
11/18/2023
如答案中所述:使用 Application.Current.Dispatcher 或以某种方式将 UI Dispatcher 作为参数传递给视图模型。
评论