View is not updated when on a separate thread

若如初见. 提交于 2019-12-12 05:36:59

问题


I am trying to load some data in a separate thread, then add the loaded data to an ObservableCollection and update the view through ba binding.

First, I was doing the following:

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();
}

This gave the following error:

This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.

So I read on this forum that I should use the Dispatcher, so I put this.Overview.Add(tvSeries) into a call to the Dispatcher.

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

Now, it doesn't crash anymore but the view is not updated. Nothing happens, the view is just empty. I have tested the functionality by running it on the main thread. Then the view is updated correctly.

Does anyone know why the view is not updated and how I can fix this?

UPDATE

The below approach seems to work and it seems to do everything asynchronously. Can anyone confirm that this is the right approach for doing things asyncronously?

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

回答1:


This is because you will need to tell WPF Dispatcher to handle the threading activity.

Check this article for more of the core details, and this one for some additional examples.

The reading can be a bit heavy, but if you're working with WPF, it's well worth learning about how the Dispatcher works.

EDIT: The second article actually explicitly mentions your problem.

Lastly, don't forget that ObservableCollection will only fire INPC events for add / remove actions, and not individual element changes. For that you'll need to implement INPC on the underlying items themselves.




回答2:


I would go for a thread-safe ObservableCollection<T> so you don't have to marshal the calls every time :)

Check out Sasha Barber's implementation: ThreadSafeObservableCollection « Sacha's blog.




回答3:


also try to change the method from BeginInvoke to Invoke.

edit

try it as:

this.Dispatcher.Invoke(new Action(()=>
{
    this.Overview.Add(tvSeries);
});


来源:https://stackoverflow.com/questions/13192247/view-is-not-updated-when-on-a-separate-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!