I'm currently writing a small program that churns on a repetitive task
while displaying a progress & cancel modeless dialog. I've been having
problems due to threadlocking, and I was wondering if anyone could
give me some advice.
Basically when I create the modeless dialog, I'm assuming that C#
under the covers will be implicitly creating a new thread for the
modeless dialog's message pump. Thus I protect the state determiners
with a mutex and a semaphore. But when the main application waits for
the user to push the "Close" button on the dialog the modeless dialog
stops refreshing, as if causing the main app thread to wait stopped
the message pump for the modeless dialog. So it seems like my first
assumption was wrong - .NET doesn't create a new thread to pump the
modeless dialog.
So here are the questions I have:
1) If there is a second thread for the modeless dialog, why is it
freezing?
2) Can you direct me towards a successful modeless progress dialog?
Thanks in advance. :) Here's an overview of the application, in
pseudo-code:
public AppMainClass
{
public bool m_bCancelled;
public void DoWork()
{
// Show a modeless progress dialog.
Progress_Form oProgressDialog = new Progress_Form( this );
oProgressDialog.Show();
bool bDone = false;
while ( bDone == false )
{
// Do work...
// Check if they hit the cancel button.
if ( m_bCancelled == true )
{
bDone = true;
}
}
// Tell the modeless dialog to convert to a "Finished" dialog,
// regardless of whether we've been cancelled or not.
// Wait to close.
oProgressDialog.WaitForClose();
// Close the dialog.
oProgressDialog.Close();
}
}
ProgressDialog
{
private Mutex m_oCloseLock;
private AutoResetEvent m_oCloseSignal;
private void FinishButtonClicked(object sender, System.EventArgs e)
{
// Enter the mutex.
m_oCloseLock.WaitOne();
// If we're set to close,
if ( FinishButton.Text == "Close" )
{
// Release the semaphore to WaitForClose();
m_oCloseSignal.Set();
}
else
{
// Set us as closing required.
m_AppMainClass.InterruptProcessing();
}
// Release the mutex.
m_oCloseLock.ReleaseMutex();
}
public void WaitForClose()
{
// We've been instructed to close.
m_oCloseLock.WaitOne();
// Change the cancel button text.
FinishButton.Text = "Close";
// Release the lock.
m_oCloseLock.ReleaseMutex();
// Block on the semaphore.
// NOTE - THIS IS WHERE THE MODELESS DIALOG FREEZES.
m_oCloseSignal.WaitOne();
}
}