Close a Modal form from a worker thread.

N

nick_nw

Hi,

I'm creating a progress form. The form contains a progress bar, but
with marquee style enabled (.Net 1.1, so this is achieved via calls to
user32.dll methods).

My form has a static method that looks something like this:

public static void Show (ProgressFormWorkDelegate workMethod)
{
ProgressForm pForm = new ProgressForm ();

Thread workThread = null;
pForm.workMethod = workMethod;
if (pForm.workMethod != null)
{
workThread = new Thread (new ThreadStart
(pForm.ProgressFormWork));
workThread.Name = "ProgressForm.ProgressFormWork";
workThread.Start ();
}

pForm.ShowDialog ();
}

private void ProgressFormWork ()
{
// Execute the client's work package in this thread.
workMethod ();

// What to do here? I could enable a close button, but sometimes I
want this form to close of its own accord so that Show will return to
the caller.
}

Now I could call this.Close from the workThread method to achieve what
I want, but I worry that I'm introducing a race condition (that the
form might not have finsihed showing by this stage). Am I worrying
uneccessarily? Is there a better way to do this?
 
M

Marc Gravell

You may find it throws a cross-thread-exception if you call close on the
dialog from an unrelated (worker) thread; a solution would be to call
(assuming "this" is still the form):

this.BeginInvoke((MethodInvoker) delegate {this.Close();});

(or something similar - haven't tested it); this will send the action to the
dialog's UI thread, so it will be picked up when available (avoiding both
the race condition and x-thread exception).

Hope this helps,

Marc
 
N

nick_nw

Marc said:
You may find it throws a cross-thread-exception if you call close on the
dialog from an unrelated (worker) thread; a solution would be to call
(assuming "this" is still the form):

this.BeginInvoke((MethodInvoker) delegate {this.Close();});

(or something similar - haven't tested it); this will send the action to the
dialog's UI thread, so it will be picked up when available (avoiding both
the race condition and x-thread exception).

Hope this helps,

Marc

Thanks for your reply.

Even with this code, there exists a possibility that close could be
called before ShowDialog, meaning that when ShowDialog is called it is
called on a closed form.
 
M

Marc Gravell

True enough; perhaps use the dialog's Load event to kick-start the worker?

pForm.Load += delegate {workThread.Start ();}
pForm.ShowDialog ();

That should fix it...

Marc
 

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