Hi,
I have a problem with thread and i'm hoping someone can help me.
I start a thread with the following code...
Thread m_NewThread = new Thread(new ThreadStart(DoWork));
m_NewThread.Start();
The threaad starts find and executes the code within DoWork, for example:
private void DoWork()
{
...
//Finished work so show thread finished
ThreadFinished();
}
Again it executes the code within ThreadFinished, for example:
private void ThreadFinished()
{
....
//Thread has finished so show finish form and close
frmFinished f = new frmFinished();
f.Show();
this.Close();
}
Now this is where it goes wrong. Stepping through this code it show's the finished form as you can see it in the taskbar but as soon as the close statement is executed it closes not only the current form but the new finished form as well.
Any ideas
Thanks in anticipation...
Neil

C# Threads
Mongsreturn
First of all, your ThreadFinished() method is being called from DoWork(), which is running on a secondary thread - this means that all of the code you have in ThreadFinished() should *not* be touching any UI controls. You should alter your code to use a BackgroundWorker instead of a basic Thread object:
Thread m_NewThread = new Thread(new ThreadStart(DoWork));
m_NewThread.Start();
BackgroundWorker m_Worker = new BackgroundWorker();
m_Worker.DoWork += new DoWorkEventHandler(DoWork);
m_Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ThreadFinished);
m_Worker.RunWorkerAsync();
void DoWork(object sender, DoWorkEventArgs e)
{
/* Do your processing here - but don't touch any objects that
* inherit from Control (DoWork executes on background thread) */
}
void ThreadFinished(object sender, RunWorkerCompletedEventArgs e)
{
/* Safe to mess with Controls now (RunWorkerCompleted executes on main thread) */
//Thread has finished so show finish form and close
frmFinished f = new frmFinished();
f.Show();
this.Close();
}
However, that is probably only part of your problem. I am betting that your code sample belongs to the main form of the application - the one passed to Application.Run() in program.cs. If that is true, then calling this.Close() will cause your main application form to close, which effectively terminates your application.
HTH
Binu Jeesman
Works a treat!
Thanks...
Neil
Bahmanbj
Unfortunately at the moment I am having to use the .NET Framwork v1.1 (until we upgrade to Visual Studio 2005 sometime next year) and it doesn't support BackgroundWorker, so I'm going to be unable to do things this way.
The code sample I gave you, thankfully, does not exist in the main form of the application. Basically I am developing a small zip utility; the main form runs in the systray and when the user selects to create a new zip a new create form is shown that allows them to set certain options. The zip process is then started off in a thread i.e. the DoWork() (did it this way so I could update progressbars and such like easily). When the thread was finished what I wanted to happen was a new form (the view zip form) was shown with the newly created zip showing and the create form to close. When in reality what happens is that the view zip form shows and then closes when the create zip form closes leaving the main app form still running.
I tried one other suggestion that was to put the ZipFinished() method into the main app form and call that from the thread but the same thing happens. And finally just to get around things for now I took another suggestion (which I hated doing) which hides the create zip form, shows the view zip form and then when the view zip form is closed it goes back and closes the relevant create zip form.
So any other suggestion would be cool, or I guess I wait until we upgrade to v2.0.
Neil
howyue
thedewd
If you are unable to use framework 2.0, then you need to at least marshall the call to ThreadFinished() into the main UI thread so that your interactions with the GUI are safe. You can use Control.InvokeRequired and Control.Invoke() to accomplish this. And actually, BackgroundWorker does this for you, just in a cleaner way.
private void Form1_Load(object sender, EventArgs e)
{
Thread m_NewThread = new Thread(new ThreadStart(DoWork));
m_NewThread.IsBackground = true; // this prevents the extra thread from blocking an application shutdown
m_NewThread.Start();
}
void DoWork()
{
/* Do your processing here - but don't touch any objects that
* inherit from Control (DoWork executes on background thread) */
Thread.Sleep(5000); // simulating some work
ThreadFinished();
}
delegate void ThreadFinishedEvent();
void ThreadFinished()
{
// Marshall back into the main thread if needed
if (this.InvokeRequired)
this.Invoke(new ThreadFinishedEvent(ThreadFinished));
else
{
/* Safe to mess with Controls now */
//Thread has finished so show finish form and close
//frmFinished f = new frmFinished();
//f.Show();
//this.Close();
MessageBox.Show("Done"); // doing stuff with GUI controls
}
}
HTH
TallMike