No BackgroundWorker Allowed

joe_pool_is

Contributor
Joined
Jan 18, 2004
Messages
507
Location
Longview, TX [USA]
I've got a really nice routine I wrote with a BackgroundWorker, it works beautifully, and reduces the time of looking up my parts in our database from 4 seconds to under 1 second.

At the heart of my BackgroundWorker is the DoWork delegate. It looks up information from 5 different tables in our database, but instead of processing that data, the data is transferred to the ProgressChanged delegate so the DoWork delegate can go on to query the next table. When the entire process is finished, the RunWorkerCompleted delegate displays the result of all the information to my form.

I want to use this time saving technique on my Windows Mobile applications. I know this message board does not have a Windows Mobile section, so I'll tell you my problem: The Windows Mobile "reduced feature" set does not include the BackgroundWorker class, but rather it includes the System.Threading namespace only.

Now, I am struggling to find out how I can achieve the same techniques using the System.Threading namespace only.

I want to find a way to duplicate things I do in my BackgroundWorker class in the System.Threading namespace. Here are the key elements I want to keep from my BackgroundWorker delegates:

DoWork:
My main issue here is finding out how to implement the ReportProgress method, as detailed below:
Code:
void Worker_GetData(object sender, DoWorkEventArgs e) {
  BackgroundWorker worker = sender as BackgroundWorker;
  MyParameter obj = (MyParameter)e.Argument;
  string partNumber = obj.PartNumber;
  string sqlText;
  using (SqlConnection con = new SqlConnection(obj.ConnString)) {
    sqlText = "SELECT * FROM Table1 WHERE (PartNumber=@PartNumber)";
    using (SqlDataAdapter da = new SqlDataAdapter(sqlText, con)) {
      DataTable table = new DataTable();
      da.SelectCommand.Parameters.Add("@PartNumber", SqlDbType.Char, 10).Value = partNumber;
      da.Fill(table);
      worker.ReportProgress(1, table);
    }
    sqlText = "SELECT * FROM Table2 WHERE (PartNumber=@PartNumber)";
    using (SqlDataAdapter da = new SqlDataAdapter(sqlText, con)) {
      DataTable table = new DataTable();
      da.SelectCommand.Parameters.Add("@PartNumber", SqlDbType.Char, 10).Value = partNumber;
      da.Fill(table);
      worker.ReportProgress(2, table);
    }
    // etc. for all 5 tables
  }
}
The ProgressChanged delegate also does a lot of work for me:
Code:
void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
  lock (_objProgress) {
    DataTable table = (DataTable)e.UserState;
    switch (e.ProgressPercentage) {
      case 1:
        // process Table1 information
        break;
      case 2:
        // process Table2 information
        break;
      // etc. for all 5 tables
    }
  }
}
If I use System.Threading, how would I:
  1. Report the thread's progress back to the main thread
  2. Catch messages from my thread
  3. Know when my thread has completed
I have found numerous examples on the web on how to use the System.Threading namespace, but no one gets into how to pass class objects from the thread back like I am able to do in the BackgroundWorker class. The closest I have found is to invoke a textbox or other basic control.

Thanks in advance for your input,
Joe
 
Back
Top