【问题标题】:Observe Collection (Bind To Datagid) - Error Threading观察集合(绑定到 Datagid) - 错误线程
【发布时间】:2011-11-08 15:56:21
【问题描述】:

我有以下设置:

public class Monitor
{
    public ObservableCollection<People> listOfPeople = new ObservableCollection<People>();


    public dosomework() {
        Thread t = new ThreadStart(longwork);
        t.Start();
    }

   public longwork() {
        listOfPeople.Add(new People());
        Thread.Sleep(10000);

   }

}

public class People : INotifyPropertyChanged
{
    int _age;
    public int Age
    {
        get { return _age; }
        set
        {
            _age = value;
            Notify("Age");
        }
    }
}

public class UI : Window
{
    Monitor md = new Monitor();
}

我想将数据网格绑定到可观察集合 (datagrid.ItemSource = md.listOfPeople),但是,我遇到了线程错误。另外,如果我不在新线程上做长时间的工作,那么 UI 只会在 longwork 函数完成后更新。我认为绑定可以避免这个问题。

任何帮助表示赞赏。

【问题讨论】:

标签: c# wpf multithreading binding collections


【解决方案1】:

正如其他人所提到的,如果您在 UI 以外的线程上执行任何工作,则必须分派到 UI 线程以实际更新绑定到 UI 元素的任何元素。

在您的示例中,这将相当容易。只需将窗口的Dispatcher (msdn) 传递给Monitor 并使用它进行相应的调度:

...
Monitor md = new Monitor(this.Dispatcher);
...
public Monitor(Dispatcher dispatcher)
{
     _dispatcher = dispatcher;
}
...
public longwork() {
    _dispatcher.BeginInvoke((Action)(()=>listOfPeople.Add(new People()));
    Thread.Sleep(10000);

}

你可以打电话给Dispatcher.Invoke而不是Dispatcher.BeginInvoke,但是如果你不关心结果并且想快速前进,BeginInvoke是你的朋友。

【讨论】:

    【解决方案2】:

    绑定只是“监听变化的其他代码”,所以线程仍然是一个问题。

    通常的解决方法是在 UI 线程上执行添加到列表,因为这是 Grid 将要监听的地方,但如果为单个元素运行这将导致性能不佳。

    最好将添加的内容批处理到在后台线程上运行的临时列表中,并每隔一段时间(每 100 个项目?)调用 AddRange 以将该批处理移动到 UI 集合中,以提供更好的响应和定期 DataGrid 更新。

    【讨论】:

      【解决方案3】:

      数据绑定数据网格订阅了 CollectionChanged 事件。根据我的经验,CollectionChanged 事件会在导致集合更改的任何线程上引发。在这种情况下,它不是 UI 线程。由于 UI 元素只能从 UI 线程修改,并且事件是在非 UI 线程上引发和处理的,因此您将收到“线程错误”。

      如上所述,一个简单的解决方案是仅从 UI 线程修改 ObservableCollection。

      如果您使用的是 WPF 或 Silverlight,则所有 FrameworkElements 都有一个 Dispatcher 属性,您可以使用该属性在 UI 线程上执行工作。另见:http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherobject.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-14
        • 2013-05-21
        • 1970-01-01
        • 2020-12-29
        相关资源
        最近更新 更多