WPF:从Dispatcher修改CollectionView仍然会抛出错误

时间:2010-05-13 21:45:42

标签: c# wpf dispatcher

我有以下一些代码可以在用户离开时修改可观察的“屏幕”集合。

void OnUserLeft(int roomId, int userId, string username)
    {
        client.ClientDispatcher.Invoke(
            (Action<int>)((id) => 
            {
                Console.WriteLine("Hello before the storm!");
                var screensToCheck = client.Screens.Where(s => s.CpuId == id).ToList();
                screensToCheck.Each(s => client.Screens.Remove(s));
                Console.WriteLine("Hello there!");
            }), userId);
    }

这包含在对客户端Dispatcher的调用中,据说可以解决与CollectionViews相关的线程问题。但是,我仍然遇到以下异常:

  

这种类型的CollectionView不支持从与Dispatcher线程不同的线程更改其SourceCollection。

您在上面看到的Dispatcher是在WPF应用程序的MainViewModel中设置的(我们使用的是MVVM),如下所示:

public Dispatcher ClientDispatcher
{
    get { return Dispatcher.CurrentDispatcher; }
}

1 个答案:

答案 0 :(得分:6)

来自CurrentDispatcher的文档:

  

获取当前正在执行的线程的Dispatcher,并创建一个新的Dispatcher(如果尚未与该线程关联)。

看起来你正在访问CurrentDispatcher 而不在你的UI线程中,并在它上面调用你的操作(即,Invoke完全没有效果,因为你所在的线程没有Dispatcher;当场创建一个新的调度程序,然后调用它。)

您应该在创建Dispatcher.CurrentDispatcher实例的位置保存Client的值(假设您是在UI线程中执行此操作),例如:

class Client {
    Client() {
        this.OwningDispatcher = Dispatcher.CurrentDispatcher;
    }

    Dispatcher OwningDispatcher { get; private set; }
}

如果您的Client实例未在UI线程中创建,则需要某种方法来获取Dispatcher的正确值。