I'm unsure as to the objective behind creating a new thread. But if this is because you wish for the UI to remain responsive and allow the user to go about doing other things while thje calculation takes place, use a BackgroundWorker instead.
1. Add a BackroundWorker instance
Code:
using System.ComponentModel;
public partial class MainForm : Form
{
/*...*/
private BackgroundWorker bgWorker = new BackgroundWorker();
/*...*/
}
2. Subscribe to key BackgroundWorker events
Code:
bgWorker.WorkerReportsProgress = true;
bgWorker.WorkerSupportsCancellation = false;
bgWorker.DoWork += bgWorker_DoWork;
bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted;
bgWorker.ProgressChanged += bgWorker_ProgressChanged;
3. Create the events
Code:
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
// This is where you code the actual task.
// I prefer to have it on its separate method and call it from here.
// In this example I'm also passing the argument we are getting from point 4. below
// The return statement is essential for proper handling of RunWorkerCompleted or if
// you wish to implement a background task cancellation feature.
e.Result = DoSomething((string)e.Argument, sender);
//note: in here you are already on a separate thread. Do not access your objects from
//here. Only from the two events below.
}
private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// This is where you put what to do when the Background Worker is done.
// Here we are back to the main thread. So you are free to access your UI objects.
if (e.Error != null)
// always do this check. Exceptions that may happen inside DoWork are finally
// processed here. Check e.Error for the actual exception, if any.
else
{
// all is well. The thread is finished and we can add any final code in here
}
}
private void bgWorker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
//the progressChanged event is called at your discretion from within your DoWork code.
//Or, on this example case from within DoSomething as you willl see below.
//While within this event you are back at the main thread, so you can update controls,
// read controls and such.
this.progBar.Value = e.ProgressPercentage;
}
4. Create the method that will do the actual work as normal
Code:
private DoSomething(string str, object sender)
{
// Your actual work. I prefer to not populate DoWork and instead create a separate
// method and call it from DoWork.
Thread.Sleep(2000);
//If you look back at DoWork, I'm also passing here the worker object.
//time to use it now to report the progress.
//If you don't need to report progress, you don't need to pass it
BackgroundWorker worker = sender as BackgroundWorker;
//here we fire up the ProgressChanged Event above
worker.ReportProgress(50);
Thread.Sleep(2000);
}
5. All Done. How to Implement?
Code:
// Simply call RunWorkerAsync() from anywhere in your code where you need this work to
start.
// On this example I decided to also pass a string argument. This string is sent to DoWork
// and readable from within through e.Argument as you can see above. And then passed
// onto DoSomething.
// Because DoWorkEventArgs.Argument is actually of the object type, you can pass
// anything. Including your own objects.
bgWorker.RunWorkerAsync("Hello World!");
This should get you started.
Check your documentation on the BackgroundWorker for more information.