views:

27

answers:

2

Hi,

in WPF application I load a list of business objects by WCF to a listbox.
I want to load it in another thread and display a progressbar window.

But how? I need to call WCF service in the second thread and return its return value to the first (UI) thread. And this is the point I don't know. How to return? Or what should be the correct workflow of calling for data at background and displaying of progress?

Now I:
- show the progress window
- create a new thread and call the WCF service
- return values <-- I don't know
- close window

But - is this workflow right?

I don't want to use a backgroundworker because I can call many different WCF services, not only one I could write into the DoWork method.

I have a WCFClient class in which I call all services I need. Here is a one of the methods (all methods are same only calls different services):

public class Client
{
    public List<BusinessDto> GetBusinesses(int userID)
    {
        OnConnecting();

        ServiceClient client = null;
        BusinessDto[] dtos = null;
        try
        {
            client = new ServiceClient();
            dtos = client.GetBusinesses(userID);
        }
        catch
        {
            MessageBox.Show(Properties.Resources.ConnectionNotSucessful, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Error);
        }
        finally
        {
            if (client != null) client.Close();

            OnClosing();

        }
        return dtos.ToList();
    }
}

I'm catching an Onconnecting and OnClosing events of WCFClient and opening and closing a new window with progressbar.

But I do not call WCF services in a new thread, because I don't know how.

Thanks, I'm trying do that unsuccessfuly for a two days.

A: 

BackgroundWorker is your friend. It does the thread marshalling for you, leaving you to worry about only doing the actual work.

HTH,
Kent

Kent Boogaart
A: 

I don't want to use a backgroundworker because I can call many different WCF services, not only one I could write into the DoWork method.

Well, first, you can decide which of many DoWork methods you want to call at the time you prepare the BackgroundWorker. But you can also (and this is probably more maintainable) write a DoWork method of arbitrary complexity. You can write a DoWork method that takes an argument of type Client, and have it call a member method on that object, for instance. There's absolutely nothing limiting about this method.

The way I'd implement a progress bar window:

  1. Implement a Task class that exposes three methods: SetUp, Execute, and TearDown, as well as a Status property, which is a struct containing int PercentComplete and string Message. Implement INotifyPropertyChanged.
  2. Implement a protected UpdateStatus method that updates Status and raises PropertyChanged.
  3. Build a modal window that implements a ShowDialog(Task t) method. In that method, call t.SetUp(), then create a BackgroundWorker.
  4. Handle t.PropertyChanged and have the handler raise the BackgroundWorker's ProgressChanged event.
  5. Have the BackgroundWorker's ProgressChanged event handler use t.Status to update the UI,
  6. Have the BackgroundWorker's DoWork event handler call t.Execute().
  7. Have its its RunWorkerCompleted event handler both handle exceptions (do not neglect this!) and call t.TearDown().
  8. Build and test Task subclasses as needed.
  9. Whenever you need to display a progress bar window, instantiate the appropriate Task, set whatever properties it needs, and then call ProgressBarWindow.ShowDialog(t). This will display the window and block and wait while the background process runs, updating the UI as it goes; it will return after t.TearDown() gets called.
Robert Rossney