locked
Backgroundworker and asynchronous methods RRS feed

  • Question

  • Hi,

      On startup, my app (WP8) needs to connect to a number of sites, login, and pull some data before moving on the main page. I'm trying to use Backgroundworkers/HttpClients for this task. The problems is that need to call some asynchronous helper methods but even if i call .Result() on them, further in the call chain, there are other asynchronous methods and when they are hit, apparently my Backgroundworkers exit early and the app is entered in an uninitialized state.

    What is the correct way of calling asynchronous methods from Backgroundworkers?

    Thanks in advance,

      Nik

    Monday, March 3, 2014 12:50 PM

All replies

  • Yes, you must block before the task exits. You can wait on TaskCompletion, or semaphores, await, WaitAll etc. Once the task ends everything is torn down.

    http://pauliom.wordpress.com


    • Edited by pkr2000 Monday, March 3, 2014 2:45 PM
    Monday, March 3, 2014 2:44 PM
  • Thanks for the pointers, I'm still having some problems, though.

    I have a several BackgroundWorkers like

    LoginBackgroundWorker backgroundWorker = new LoginBackgroundWorker();
    backgroundWorker.DoWork += new DoWorkEventHandler(Login);
    backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Ready);
    backgroundWorker.ProgressChanged += Progress;
    backgroundWorker.RunWorkerAsync();
    backgroundWorker.WorkerReportsProgress = true;

    private void Login(object sender, DoWorkEventArgs e)
    {
         LoginBackgroundWorker loginBackgroundWorker = sender as LoginBackgroundWorker;
         Handshake handshake = App.Engine.Handshake(loginBackgroundWorker.Server).Result;
         (sender as LoginBackgroundWorker).ReportProgress(0, handshake);
    }

    private void Progress(object sender, ProgressChangedEventArgs e)
    {
    ...
    }

    void Ready(object sender, RunWorkerCompletedEventArgs e)
    {
       this.Dispatcher.BeginInvoke(() =>
       {
           ...
       });
    }

    the Handshake method in Login is async but I can't do await on it without changing the signature of the DoWork, so I'll have to do an .Result on the call, right?

    Where did you mean the semaphores should come in? 

    Thanks in advance,

      Nik

    Tuesday, March 4, 2014 8:21 AM
  • private void Login(object sender, DoWorkEventArgs e)
    {
         LoginBackgroundWorker loginBackgroundWorker = sender as LoginBackgroundWorker;
         var task = App.Engine.Handshake(loginBackgroundWorker.Server);
         task.Wait(); // Wait for the task to complete
         Handshake handshake = task.Result;
         (sender as LoginBackgroundWorker).ReportProgress(0, handshake);
    }
    Was this what you were looking for?

    • Edited by Johannes Lappi Tuesday, March 4, 2014 9:10 AM remove extra code block
    Tuesday, March 4, 2014 9:06 AM
  • Thanks for the pointer, it got me digging more into my code and I noticed that there was another underlying problem and a swallowed exception. Embarrassing :-/ The plain .Result call I had earlier works for me now
    Tuesday, March 4, 2014 11:01 AM