views:

43

answers:

1

I'm having trouble understanding how to use threads. In a delegate that is called as needed to allow the user to select from a collection of projects, the first instantiation is costly due to data retrieval. The method looks like so:

private void _doStandAloneProjectPickSession(ProjectDataMode dataMode) {
   var picker = new ProjectPicker();
   var svc = _getFilterService(dataMode); ===> this is time consuming**
   _vm = new ProjectSelectionViewModel(picker, svc);
   _vm.RequestClose += _onClosing;

   _window = picker;
   _window.ShowDialog();
  }

Is the basic idea to start the long running process in it's own thread (ie new Thread(doSomething).Start and then use the Dispatcher (in a wpf app) to cut in while the process is happening? I want to do something like the pseudo code below, but I can't get it to work.

private void _doStandAloneProjectPickSession(ProjectDataMode dataMode) {
   ...

   // let user know the system is fetching data
   // _getDispatcher.BeginInvoke(DispatcherPriority.Background, ()=>SetStaus("Fetching data...");


     IProjectFilterService svc = null;

   // fetch the data
   // new Thread(_getFilterService(dataMode)).Start();

   _vm = new ProjectSelectionViewModel(picker, svc);
   _vm.RequestClose += _onClosing;

   ...
  }

Can someone please show me what working code might look like?

Cheers,
Berryl

+3  A: 

You have the basic idea correct: do time-consuming work on a background thread and join back to the UI thread only when necessary (ie. when you're updating UI components). However, I suggest you simplify your life by just using the BackgroundWorker component. It does the synchronization back to the UI thread for you:

var backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += delegate
{
    //do expensive work here, optionally calling ReportProgress to report progress
};
backgroundWorker.ProgressChanged += delegate
{
    //update the UI. eg. a ProgressBar
};
backgroundWorker.RunWorkerCompleted += delegate
{
    //all done - update the UI with the results
};

//kick it off!
backgroundWorker.RunWorkerAsync();

HTH, Kent

Kent Boogaart
whoa, the progress changed and run worker completed delegates run on the calling thread?
Firoso
@firoso: Indeed they do. That's the point of the component. It uses the current SynchronizationContext to marshal the execution of these event handlers to the UI thread.
Kent Boogaart
`BackgroundWorker` simplifies this whole problem amazingly well.
Robert Rossney
Any thoughts on Synchronization Context (http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx)? Or thoughts on the BackgroundWorker and TDD? I usually don't get something fully until I can test it, but it sure seems an upgrade over hand-rolled Dispatcher calls. Thanks!
Berryl