Call method in view model call which take/consume much of time - Multithreading in VM

Jan 13, 2011 at 9:53 PM
Edited Jan 13, 2011 at 9:56 PM

Hi I try solve this situation. I have WPF app with MVVM design.

In WPF app I use service from external assembly. It works good.

Problem is. I bind observable dictionary to listbox. Listbox can consist from 0 to 400 items. I have data template on listbox item it consist with image and som texbox. Listbox is like contact list in skype or google talk.

I call every 3-4 sec method from service, wich returns new data as dictionary. An with this data aj refresh Listbox.

My code look in view model like this:

 

   private DispatcherTimer _dispatcherTimer;
private MyObservableDictionary<string, UserInfo> _friends;
//temp
private MyObservableDictionary<string, UserInfo> _freshFriends;

//bind on listbox
public MyObservableDictionary<string, UserInfo> Friends
{
get { return _friends; }
set
{
_friends = value;
NotifyOfPropertyChange(() => Friends);
}
}

//in constructor of view model I have this:
_dispatcherTimer = new DispatcherTimer();
_dispatcherTimer.Tick += DispatcherTimer_Tick;
_dispatcherTimer.Interval = TimeSpan.FromSeconds(3);
_dispatcherTimer.Start();

// on timer tick I call method from service
private void DispatcherTimer_Tick(object sender, EventArgs eventArgs)
{

//get new data from server
//method GetFriends take much of time
_freshFriends = _service.GetFriends(Account);

//delete old data
_friends.Clear();

//refresh
foreach (var freshFriend in _freshFriends)
{
Friends.Add(freshFriend);

}
}

 

As I said, problem is that method GetFriends from service take much of time and my app freezes.

How can solve this problem? In winforms app I use background worker, but this is my first WPF app with MVVM. It exist any "patern" or "design" how call method which consume much of time in view model class? Call this method in another thread?

Developer
Jan 13, 2011 at 10:13 PM
Edited Jan 13, 2011 at 10:13 PM

You could call it in another Thread for example, somthing like:

// Create a new Thread.
Thread workerThread = new Thread(GetFriends);

 // Run the Thread in the background.
workerThread .IsBackground = true;
 
// Start trhe Thread.
workerThread .Start();

/// Method that does all the work
private void GetFriends()
{
   ...
   ...
   //refresh
   foreach (..)
   {
      // Add friends to the MyObservableDictionary
      Friends.Add(freshFriend);
   }
   ...
}


Coordinator
Jan 14, 2011 at 8:28 AM

The Answer of Marko is probably what you need. Keep in mind that if the Friend collection is an observable collection, you need to dispatch to the UI thread. Luckily, the ViewModelBase has a Dispatcher property ;)