WPF 未释放视图模型

WPF not disposing viewmodel

提问人:Luka 提问时间:11/18/2023 更新时间:11/18/2023 访问量:47

问:

我遇到了关于 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,因为可以从另一个线程调用此刷新方法,即。计时器。

如何摆脱这个?

WPF NET-4.5 调度程序

评论


答:

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 作为参数传递给视图模型。