开发者

Cannot update UI using the UI thread Dispatcher?

开发者 https://www.devze.com 2023-03-29 04:08 出处:网络
I designed a WPF application based on MVVM pattern and I need to get large amount of data from a webservice, and i do it with a BackgroundWorker inside the ViewModel. To modify the observable collecti

I designed a WPF application based on MVVM pattern and I need to get large amount of data from a webservice, and i do it with a BackgroundWorker inside the ViewModel. To modify the observable collection i have to use a dispatcher and the problem is here, even if i pass by reference UI Dispa开发者_如何转开发tcher it dosen't work, it is like I use the inner dispatcher and my application get freezed until all data are retrived.

I try to get the UI Dispatcher in several ways, Dispatcher.CurrentDispatcher, Application.Dispatcher, App.Current.Dispatcher... doing some researches I read that it should be works, does someone have any suggestions?

Thank you Marco

Update

Here some code: This is how I pass the Dispatcher to the ModelView

void AppWindow_Loaded(object sender, RoutedEventArgs e)
{
     this.DataContext = new ModelViewApplication(System.Windows.Threading.Dispatcher.CurrentDispatcher);
}

Then I try to get data in this way

public ModelViewApplication(Dispatcher _dispatcher)
{
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += new DoWorkEventHandler(getData);
    bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(completedData);

    bw.RunWorkerAsync();
}

public void getData(object sender, DoWorkEventArgs e)
{
    _dispatcher.Invoke(DispatcherPriority.Normal,
        new Action(
            delegate()
                 {
                 //Connect to webservice and retrieve data
                 ....
                 }));
}

It seems like the multithread dosen't work


Use the BackgroundWorker to get your data, then use the RunWorkerCompleted to update the ObservableCollection. You shouldn't need the Dispatcher at all

public ModelViewApplication()
{
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += new DoWorkEventHandler(getData);
    bw.RunWorkerCompleted += completedData;

    bw.RunWorkerAsync();
}

public void getData(object sender, DoWorkEventArgs e)
{
    //Connect to webservice and retrieve data
    e.Result = WebService.GetData();
}

private void completedData(object sender, RunWorkerCompletedEventArgs e)
{
    MyCollection = new ObservableCollection<SomeClass>((IList)e.Results);
}


Here is a sample which may help you implementing the task and UI Updates. You can easily convert the following sample to you scenario. You can have a look at my blog which has detailed Explanation regarding this error and solution

http://bathinenivenkatesh.blogspot.com/2011/07/wpf-build-more-responsive-ui.html

ObservableCollection images = new ObservableCollection(); 
TaskFactory tFactory = new TaskFactory(); 
tFactory.StartNew(() => 
{ 
    for (int i = 0; i < 50; i++) 
    { 
        //GET IMAGE Path FROM SERVER 
        System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate() 
        { 
            // UPDATE PROGRESS BAR IN UI 
        }); 

        images.Add((""); 
    } 

}).ContinueWith(t => 
{ 
    if (t.IsFaulted) 
    { 
        // EXCEPTION IF THREAD IS FAULT 
        throw t.Exception; 
    } 
    System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate() 
    { 
        //PROCESS IMAGES AND DISPLAY 
    }); 
});
0

精彩评论

暂无评论...
验证码 换一张
取 消