Threadlock on a Modeless Dialog

C

Carmine

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();
}
}
 
J

Joel Hendrix [MSFT]

You're correct that a message pump isn't set up for you automatically when
you create your modeless dialog. The approach I would recommend would be
to do all of your intensive work on a backround thread that periodically
communicates to the UI thread with progress update. Here's some
pseudo-code on how this would work.

public class MainApp
{
public void FunctionThatInvokesIntensiveWork()
{
Thread worker = new Thread(new ThreadStart(WorkerFunction));
DialogThatDisplaysUpdate update = new DialogThatDisplaysUpdate();
update.Show();
worker.Start();
}

public void WorkerFunction()
{
while (intensiveWorkNotFinished)
{
// do more work
// communicate back to the UI thread the status of the operation
}
}
}

Here's a great article that discusses this very topic:

http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/default.aspx

hth

-Joel
--------------------
From: (e-mail address removed) (Carmine)
Newsgroups: microsoft.public.dotnet.languages.csharp
Subject: Threadlock on a Modeless Dialog
Date: 28 Jun 2004 13:35:26 -0700
Organization: http://groups.google.com
Lines: 104
Message-ID: <[email protected]>
NNTP-Posting-Host: 65.78.25.41
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: posting.google.com 1088454927 28894 127.0.0.1 (28 Jun 2004 20:35:27 GMT)
X-Complaints-To: (e-mail address removed)
NNTP-Posting-Date: Mon, 28 Jun 2004 20:35:27 +0000 (UTC)
Path: cpmsftngxa10.phx.gbl!TK2MSFTNGXA01.phx.gbl!cpmsftngxa06.phx.gbl!TK2MSFTNGP08
.phx.gbl!newsfeed00.sul.t-online.de!t-online.de!border2.nntp.dca.giganews.co
m!border1.nntp.dca.giganews.com!nntp.giganews.com!news.glorb.com!postnews2.g
oogle.com!not-for-mail
Xref: cpmsftngxa10.phx.gbl microsoft.public.dotnet.languages.csharp:254726
X-Tomcat-NG: microsoft.public.dotnet.languages.csharp

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();
}
}

This reply is provided AS IS, without warranty (express or implied).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top