0

我正在尝试在单独的线程中加载一些数据,然后将加载的数据添加到 ObservableCollection 并通过 ba 绑定更新视图。

首先,我正在执行以下操作:

public OverviewViewModel()
{
    Thread thread = new Thread(new ThreadStart(delegate
    {
        TheTVDB theTvdb = new TheTVDB();
        foreach (TVSeries tvSeries in theTvdb.SearchSeries("Dexter"))
        {
            this.Overview.Add(tvSeries);
        }
    }));
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
}

这给出了以下错误:

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

所以我在这个论坛上读到我应该使用 Dispatcher,所以我this.Overview.Add(tvSeries)打电话给 Dispatcher。

Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate
{
    this.Overview.Add(tvSeries);
},
DispatcherPriority.Normal);

现在,它不再崩溃,但视图没有更新。什么都没有发生,视图只是空的。我已经通过在主线程上运行它来测试功能。然后正确更新视图。

有谁知道为什么视图没有更新以及如何解决这个问题?

更新

以下方法似乎有效,并且似乎异步执行所有操作。谁能确认这是异步做事的正确方法?

Dispatcher.CurrentDispatcher.BeginInvoke(new Action(delegate
{
    TheTVDB theTvdb = new TheTVDB();
    foreach (TVSeries tvSeries in theTvdb.SearchSeries("Dexter"))
    {
        this.Overview.Add(tvSeries);
    }
}),
DispatcherPriority.Background);
4

3 回答 3

1

这是因为您需要告诉 WPF Dispatcher 来处理线程活动。

查看这篇文章了解更多核心细节,这篇文章了解一些额外的例子。

阅读内容可能有点繁重,但如果您使用的是 WPF,那么非常值得了解 Dispatcher 的工作原理。

编辑:第二篇文章实际上明确提到了您的问题。

最后,不要忘记 ObservableCollection 只会为添加/删除操作触发 INPC 事件,而不是单个元素更改。为此,您需要在基础项目本身上实施 INPC。

于 2012-11-02T09:42:35.980 回答
0

我会选择线程安全的ObservableCollection<T>,这样您就不必每次都编组调用:)

查看 Sasha Barber 的实现:ThreadSafeObservableCollection « Sacha 的博客

于 2012-11-02T09:11:57.640 回答
0

还尝试将方法从 BeginInvoke 更改为 Invoke。

编辑

试试看:

this.Dispatcher.Invoke(new Action(()=>
{
    this.Overview.Add(tvSeries);
});
于 2012-11-02T09:21:31.733 回答