Skip to content Skip to sidebar Skip to footer

How To Start A Long Running Process In A Separate Thread

ok here we go last part almost done! one error to go hmmmmm. This is using the suggestion and is complaining about delegates i think. using System; public partial class Form1

Solution 1:

You have many problems in your code:

  • The call to Application.Run() is a blocking call. It won't return until you close your form. So your thread starts when your application is about to exit.

    Just start your thread before calling Run():

    ThreadaniSql=newThread(newThreadStart(getSalesFigures));
    aniSql.Start();
    Application.Run(newForm1());
    

    A Tip: Start using the debugger and step through your code. You would have noticed that your thread function is never reached.

  • You create a second instance of Form1 in the function GetSalesFigures. You have to use the existing instance when polling the state of the checkbox.

  • Your thread will perform only a single check and then it returns. You have to write some code in GetSalesFigures to wait for the user to check the checkbox. Otherwise nothing will happen. You can use a ManualResetEvent for waiting on an event:

    ManualResetEvent mre = new ManualResetEvent(false);
    
    voidYourThreadFunc() {
        // Wait until someone signals mre
        mre.WaiteOne();
        // start sql
        ...
    }
    

    In your form:

    privatevoidbutton1_Click(object sender, EventArgs e)
    {
        // trigger the WaitHandle to signal the waiting thread
        mre.Set();
    }
    

Solution 2:

Fixed some minor spelling errors, didn't have a compiler at hand back then. To your last error: Just provide the accCollection.Text as parameter to your method. See the updated button1_Click() and GetsalesFigures(String Acct). This is how my Partial Class : Form looks like

publicForm1()
{
  InitializeComponent();
  pictureBox2.Visible = false;
}
privatevoidForm1_Load(object sender, EventArgs e) 
{ 
  AutofillAccounts(); 
}  
privatevoidbutton1_Click(object sender, EventArgs e)
{
  checkBox1.Checked = true;
  string acct = accCollection.Text;
  Task t = new Task(() => GetsalesFigures(acct)); 
  t.Start();
}
privatevoidGetsalesFigures(String Acct)
{
  // (...)//pictureBox2.Visible = true; use SetPictureBoxVisibility
  SetPictureBoxVisibility(true);
  //checkBox1.Checked = true; use SetCheckBoxValue
  SetCheckBoxValue(true);
  // (...)
  SetCheckBoxValue(false);
  SetPictureBoxVisibility(false); 
  // (...)
  acct = Acct;
 // (...)
 SetDataGrid(true, dataSet1, "Pareto", DataGridViewAutoSizeColumnsMode.AllCells);
}
privatevoidAutofillAccounts()
{
   // (...)while (readacc.Read())             
    {                 
      AddItem(readacc.GetString(0).ToString());             
    }
}
privatevoidSetCheckBoxValue(bool IsChecked)
{
  if (checkBox1.InvokeRequired)
  {
    pictureBox2.Invoke(new Action<bool>(SetCheckBoxValue), new Object[] { IsChecked });
  }
  else
  {
    checkBox1.Checked = IsChecked;
  }
}
privatevoidSetPictureBoxVisibility(bool IsVisible)
{
  if (pictureBox2.InvokeRequired)
  {
    pictureBox2.Invoke(new Action<bool>(SetPictureBoxVisibility), new Object[] { IsVisible });
  }
  else
  {
    pictureBox2.Visible = IsVisible;
  }
}
// Your latest commentprivatevoidAddItem(stringvalue)
 {
  if (accCollection.InvokeRequired)
  {
    accCollection.Invoke(new Action<string>(AddItem), new Object[] {   value });
  }
  else
  {
    accCollection.Items.Add(value);
  }
}
privatevoidSetDataGrid(bool AutoGenerateColumns, Object DataSource, String DataMember, DataGridViewAutoSizeColumnsMode Mode)
{
  if (this.dataGridView1.InvokeRequired)
  {
    this.dataGridView1.Invoke(new Action<bool, Object, String,   DataGridViewAutoSizeColumnsMode>(SetDataGrid),
                              AutoGenerateColumns, DataSource, DataMember, Mode);
  }
  else
  {
    this.dataGridView1.AutoGenerateColumns = AutoGenerateColumns;
    this.dataGridView1.DataSource = DataSource;
    this.dataGridView1.DataMember = DataMember;
    dataGridView1.AutoResizeColumns(Mode);
  }
}

And Program.cs

staticclassProgram
{
///<summary>/// The main entry point for the application.///</summary>
[STAThread]
staticvoidMain()
{
  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);
  Application.Run(new Form1());
}

To summary your problem: You have to encapsulate all control-related updates you want to call from another thread than the main thread just like I did it with the two controls.

Some ressources you might want to check for multithreading / tasks http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx http://blogs.msdn.com/b/pfxteam/archive/2009/06/30/9809774.aspx

Post a Comment for "How To Start A Long Running Process In A Separate Thread"