gpt4 book ai didi

c# - 为什么 Prism DelegateCommands 有时会导致线程异常?

转载 作者:行者123 更新时间:2023-11-30 17:40:58 38 4
gpt4 key购买 nike

下面的示例使用了 Prism 6.1 中的 DelegateCommand,但我在 5.0 中产生了同样的问题。

使用以下 View 模型(省略 View ,仅包含 2 个按钮):

public class MainWindowViewModel
{
public DelegateCommand TestCommand { get; set; }
public DelegateCommand ActionCommand { get; set; }

public MainWindowViewModel()
{
TestCommand = new DelegateCommand(()=> TestCommand.RaiseCanExecuteChanged());

ActionCommand = new DelegateCommand(() =>
{
Task.Run(() =>
{
Thread.Sleep(1000);
TestCommand.RaiseCanExecuteChanged();
});
});
}
}

如果首先调用 ActiveCommand,则会发生此异常:

An exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll but was not handled in user code

Additional information: The calling thread cannot access this object because a different thread owns it.

据我所知,这是标准的“如果您不在 UI 线程上,则不允许与 Wpf 控件对话”异常。这似乎与方法摘要不一致:

Raises Prism.Commands.DelegateCommandBase.CanExecuteChanged on the UI thread so every command invoker can requery to check if the command can execute.

此外,我过去从非 UI 线程调用此方法也没有问题。

更奇怪的是,如果首先引发 TestCommand,那么 ActionCommand 就会开始正常工作。我已经检查过,Task.Run block 中的代码在所有情况下都在非 UI 线程上运行。

不幸的是,我不能在我的真实代码中使用它作为解决方法 - 我已经尝试让 UI 线程在工作线程调用 RaiseCanExecuteChanged 之前调用它,但它没有帮助。

RaiseCanExecuteChanged 这样做有什么理由吗?任何修复或解决方法?

最佳答案

您正在 UI 线程上创建 TestCommand 并尝试在单独的线程上访问它。你不能那样做。如果您只想引发 can execute,那么只需 await Task.Run 然后调用它即可。

    public MainWindowViewModel()
{
TestCommand = new DelegateCommand(Test, CanTest);

ActionCommand = new DelegateCommand(async () =>
{
await Task.Run(() =>
{
Thread.Sleep(1000);
});

TestCommand.RaiseCanExecuteChanged();
});
}

关于c# - 为什么 Prism DelegateCommands 有时会导致线程异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33660381/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com