gpt4 book ai didi

c# - 这种类型的 CollectionView 不支持从线程更改其 SourceCollection ......在使用调度程序时?

转载 作者:行者123 更新时间:2023-11-30 23:11:56 26 4
gpt4 key购买 nike

所以我正在开发一个带有在应用程序(主应用程序)中使用的 UI 的插件。为了在主应用程序工作时使我的 UI 响应,我在其单独的线程中启动我的 UI,如下所示:

    public  void ShowDialog(IIFCConverter ifcConverter)
{

thread = new Thread(x =>
{
thread.Name = "UI-thread";
window = new MainWindow();
var mainViewModel = ServiceLocator.Current.GetInstance<MainWindowViewModel>();
mainViewModel.SetIFCConverter(x as IIFCConverter);
ViewModelLocator.MainWindow = window;
window.ShowDialog();



});
thread.SetApartmentState(ApartmentState.STA);

thread.Start(ifcConverter);

}

我第一次启动我的插件时一切正常。第二次启动它并尝试引发事件(如 OnCollectionChanged)时,我收到 NotSupportedException 消息:“这种类型的 CollectionView 不支持从不同于 Dispatcher 线程的线程更改其 SourceCollection”

这是我的方法之一:

    private void AddNewFile(AddNewFileMessage obj)
{
if (!(obj.Sender is ButtonViewModel)) return;

if (string.IsNullOrEmpty(obj.Path)) return;



var ifcFileViewModel = new IFCFileViewModel(new Common.Model.IFCFile { Path = obj.Path, Active = true });
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
ListBoxItems.Insert(ListBoxItems.Count - 1, ifcFileViewModel);
});

}

尽管我使用的是 MVVM light 的 DispatcherHelper,但我得到了这个。我曾尝试使用“普通”调度程序,但这给了我相同的结果。

首先,我很想知道为什么这样做的机制?我检查了我的线程,我可以看到 OnOllectionChanged 是从我的 UI 线程调用的。我似乎找不到第一次运行(有效)和以下运行之间线程结构的任何差异。

OnCollectionChanged called on UI-thread, right?

其次,我该怎么办?

我测试过但没有帮助的东西:

  1. 我使用来自 MVVM light 的 IoC 容器并将其注册为 LocatorProvider,但我每次初始化 UI 并将该实例设置为 LocatorProvider 时都会创建一个新的 IoC 容器。
  2. 我正在窗口的构造函数中初始化 DispatcherHelper。所以那应该在正确的线程上。
  3. 确实有效的方法是将操作包装在一个 try Catch block 中,如下所示:

    private void AddNewFile(AddNewFileMessage obj)
    {
    if (!(obj.Sender is ButtonViewModel)) return;

    if (string.IsNullOrEmpty(obj.Path)) return;



    var ifcFileViewModel = new IFCFileViewModel(new Common.Model.IFCFile { Path = obj.Path, Active = true });

    DispatcherHelper.CheckBeginInvokeOnUI(() =>
    {
    try
    {
    ListBoxItems.Insert(ListBoxItems.Count - 1, ifcFileViewModel);
    }
    catch(Exception ex)
    {

    }
    });

但是我发现这非常丑陋并且想避免它,为什么它甚至可以工作?当我将所有操作包装在 try Catch block 中时,一切似乎都运行良好。

最佳答案

好的,所以我找到了真正的问题。viewmodel 确实是在与我的插件 UI 相同的线程上创建的。

但是:我正在使用 MVVMLight 工具包中可用的 Messenger 来处理 View 模型之间的通信,但我忘记在关闭窗口时注销 View 模型。所以我第二次打开我的窗口并开始在我的 View 模型之间发送消息。第一个 View 模型使用react,这就是导致问题的原因。这也是 try-Catch-block 起作用的原因,因为正确的线程进行了第二次调用。我在 View 模型的构造函数中添加了一个日期时间,确实调用了两个不同的 View 模型。我不明白为什么我会得到那个异常(exception)。如果有的话,第一个 View 模型应该通过数据上下文连接到第一个 View 。就像 View 已连接到两个不同 View 模型的事件一样。

无论如何,它现在可以工作了:当我的窗口关闭时,我只是从消息服务中取消注册 View 模型,它就像一个魅力。

关于c# - 这种类型的 CollectionView 不支持从线程更改其 SourceCollection ......在使用调度程序时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44431062/

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