MessageBox in multi threaded app

M

Martin

Hi all,

I have a multithreaded application that has one worker thread that
does all the work in the background. There is some work that takes
some seconds of time. After that work is completed the worker thread
calls a delegate of the form using BeginInvoke. The delegate takes
data from the worker and presents results of the work to the user
using a MessageBox.


When the user does nothing during the work is in progress everything
is fine. But if the user during the work switches to another
application (so my app is not in foreground when the work finishes)
the MessageBox behaves strange - somehow it loses track of its parent
window, so when user clicks on the taskbar to get my app back to the
foreground, the MessageBox do not get to the foreground with the app,
it stays in the background. The only way how to bring it to front is
using Alt-Tab. Moreover the application does not respond to the user,
because it waits for confirmation of the MessageBox, so it the user
does not know about the problem with the MessageBox, he is very
confused and thinks that the application is dead...


Do you anyone know, where could be the problem?


Martin
 
N

Nicholas Paldino [.NET/C# MVP]

Martin,

Can you show the code that is calling MessageBox? Also, you only have
one UI thread, right? Or are you showing windows from other threads as well
(which could be the cause of your problem).
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Martin said:
Hi all,

I have a multithreaded application that has one worker thread that
does all the work in the background. There is some work that takes
some seconds of time. After that work is completed the worker thread
calls a delegate of the form using BeginInvoke. The delegate takes
data from the worker and presents results of the work to the user
using a MessageBox.

Why BeginInvoke and not simply Invoke?

Is the thread destroyed after it finish the work?
 
M

Martin

Nicholas,

I have only one UI thread. I've created a very simple app, that
behaves as my application, I'll not post the whole code that is behind
the form creation as it is a simple application created by the VS2005
wizard - one form with one button with default names (Form1, button1).

public partial class Form1 : Form
{
class Worker
{
public Form form;
public callback call;

public void DoWork()
{
Thread.Sleep(5000);
form.BeginInvoke(call, new object[] { 25 });
}
}

Worker worker;

public Form1()
{
InitializeComponent();
worker=new Worker();
worker.form=this;
worker.call=new callback(thread_callback);
}

private void button1_Click(object sender, EventArgs e)
{
Thread thread=new Thread(new ThreadStart(worker.DoWork));
thread.IsBackground=true;
thread.Start();
button1.Enabled=false;
}

delegate void callback(int result);
private void thread_callback(int result)
{
MessageBox.Show(result.ToString());
button1.Enabled=true;
}
}
 
M

Martin

Hi,





Why BeginInvoke and not simply Invoke?

Is the thread destroyed after it finish the work?

Hi,

No the thread is not destroyed after it finishes the work, it does
other things.

If I use Invoke instead of BeginInvoke, the result is the same.
Moreover the thread has a queue with other commands, so it only calls
the methods using BeginInvoke, so it is not blocked while the UI
thread is processing the results, displaying messages etc.

Martin
 
D

Doug Semler

delegate void callback(int result);
private void thread_callback(int result)
{
MessageBox.Show(result.ToString());
button1.Enabled=true;
}

uhhh, did you try:

MessageBox.Show(this, result.ToString());

There is a big difference between the two. IIRC, MessageBox.Show
without a parent sets the parent to the desktop (unless certain
conditions are met, and even then it can set it to be the active
window), which is why, when your app becomes active again, the modal
message box goes to "directly above" its parent window (the
desktop)...
 
M

Martin

uhhh, did you try:

MessageBox.Show(this, result.ToString());

There is a big difference between the two. IIRC, MessageBox.Show
without a parent sets the parent to the desktop (unless certain
conditions are met, and even then it can set it to be the active
window), which is why, when your app becomes active again, the modal
message box goes to "directly above" its parent window (the
desktop)...

Thanks, that is it. I wonder how it could happen, that I have not seen
this method in MSDN...
 
D

Doug Semler

Thanks, that is it. I wonder how it could happen, that I have not seen
this method in MSDN...

The overload is Show(IWin32Window owner, ...)

IWin32Window is one of the base interfaces for Control and
NativeWindow, which is why it works (in fact, you can parent the
MessageBox to ANY control because of this) <G>
 

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