O
olig
I'm doing some lengthy computation on a separate thread (actually its a
search) and want to display a small window with something like "Search in
progress" and allow the user to cancel the search. I am not sure what would
be the best approach.
I made a small sample, basically I have a form with a start button which
starts the computation in a new thread and display the WaitingForm which is
a simple form with a cancel button to cancel the operation.
The first approach I tried is this:
public class Form1 : System.Windows.Forms.Form
{
//Constructors and .NET generated code removed for simplicity
WaitingForm _waitingForm;
Thread _thread;
AutoResetEvent _waitHandle;
private void button1_Click(object sender, System.EventArgs e)
{
_waitHandle = new AutoResetEvent(false);
_thread = new Thread(new ThreadStart(LongComputation));
_thread.Start();
_waitingForm = new WaitingForm();
_waitingForm.button1.Click += new EventHandler(cancelHandler);
_waitingForm.Show();
_waitHandle.WaitOne();
_waitingForm.Close();
}
private void LongComputation()
{
try
{
for (int i=0; i<100; i++)
{
System.Diagnostics.Debug.WriteLine(i);
Thread.Sleep(100);
}
finally
{
_waitHandle.Set();
}
}
}
private void cancelHandler(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Canceling thread");
_thread.Abort();
}
}
However this doesn't work because the main thread is blocked on
_waitHandle.WaitOne() and does not process messages, so the waiting form is
not correctly displayed and do not respond to events and the user can't
click the cancel button. Maybe I should display this window in a separate
thread?
Then I removed the WaitHandle and I tried this:
public class Form1 : System.Windows.Forms.Form
{
//Constructors and .NET generated code cut for simplicity
WaitingForm _waitingForm;
Thread _thread;
private void button1_Click(object sender, System.EventArgs e)
{
_thread = new Thread(new ThreadStart(LongComputation));
_thread.Start();
_waitingForm = new WaitingForm();
_waitingForm.button1.Click += new EventHandler(cancelHandler);
_waitingForm.ShowDialog();
}
private void LongComputation()
{
try
{
for (int i=0; i<100; i++)
{
System.Diagnostics.Debug.WriteLine(i);
Thread.Sleep(100);
}
}
finally
{
_waitingForm.Close();
}
}
private void cancelHandler(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Canceling thread");
_thread.Abort();
}
}
This works correctlty but I don't feel it is the right way to do things. I
thing that I should use some asynchronous calls and have a callback method
to get signaled when the thread is over.
Any suggestions on the right approach to use?
olig
search) and want to display a small window with something like "Search in
progress" and allow the user to cancel the search. I am not sure what would
be the best approach.
I made a small sample, basically I have a form with a start button which
starts the computation in a new thread and display the WaitingForm which is
a simple form with a cancel button to cancel the operation.
The first approach I tried is this:
public class Form1 : System.Windows.Forms.Form
{
//Constructors and .NET generated code removed for simplicity
WaitingForm _waitingForm;
Thread _thread;
AutoResetEvent _waitHandle;
private void button1_Click(object sender, System.EventArgs e)
{
_waitHandle = new AutoResetEvent(false);
_thread = new Thread(new ThreadStart(LongComputation));
_thread.Start();
_waitingForm = new WaitingForm();
_waitingForm.button1.Click += new EventHandler(cancelHandler);
_waitingForm.Show();
_waitHandle.WaitOne();
_waitingForm.Close();
}
private void LongComputation()
{
try
{
for (int i=0; i<100; i++)
{
System.Diagnostics.Debug.WriteLine(i);
Thread.Sleep(100);
}
finally
{
_waitHandle.Set();
}
}
}
private void cancelHandler(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Canceling thread");
_thread.Abort();
}
}
However this doesn't work because the main thread is blocked on
_waitHandle.WaitOne() and does not process messages, so the waiting form is
not correctly displayed and do not respond to events and the user can't
click the cancel button. Maybe I should display this window in a separate
thread?
Then I removed the WaitHandle and I tried this:
public class Form1 : System.Windows.Forms.Form
{
//Constructors and .NET generated code cut for simplicity
WaitingForm _waitingForm;
Thread _thread;
private void button1_Click(object sender, System.EventArgs e)
{
_thread = new Thread(new ThreadStart(LongComputation));
_thread.Start();
_waitingForm = new WaitingForm();
_waitingForm.button1.Click += new EventHandler(cancelHandler);
_waitingForm.ShowDialog();
}
private void LongComputation()
{
try
{
for (int i=0; i<100; i++)
{
System.Diagnostics.Debug.WriteLine(i);
Thread.Sleep(100);
}
}
finally
{
_waitingForm.Close();
}
}
private void cancelHandler(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Canceling thread");
_thread.Abort();
}
}
This works correctlty but I don't feel it is the right way to do things. I
thing that I should use some asynchronous calls and have a callback method
to get signaled when the thread is over.
Any suggestions on the right approach to use?
olig