Hi,
I have a situation where I start a worker thread from my UI thread and I show a progress dialog while the worker thread is running. However, the worker thread might need to get some confirmation from the user during its task. So I need to close the progress dialog, show a form and then continue the progress dialog and the worker thread again. Below is a code snippet of how I do it. This seems to work pretty good, but am I doing this right? Below of the code snippet, I've listed couple of problems I face with this solution. Please help me.
When start button is pressed in mainform, it will create and start a thread class
and it shows a progress (Marquee) dialog.
void ButtonStartClick(object sender, System.EventArgs e)
{
this.threadClass = new ThreadClass(new GetConfirmation(onGetConfirmation))
Thread backgroundThread = new Thread(new ThreadStart(this.threadClass.doStuff));
backgroundThread.Start();
ShowLoadingForm(); // shows a progress dialog
}
public delegate void GetConfirmation(string text);
public void onGetConfirmation(string text)
{
if (InvokeRequired)
{
Invoke(new GetConfirmation(onGetConfirmation), new object[] {text});
}
else
{
CloseLoadingForm(); // closes progress dialog
QuestionForm form = new QuestionForm(text);
if (form.ShowDialog() == DialogResult.Cancel)
{
this.threadClass.Continue(false);
}
else
{
ShowLoadingForm(); // restores progress dialog
this.threadClass.Continue(true);
}
}
}
*** Worker thread ***
public void doStuff()
{
... //doing some stuff here
if (someCondition) // we need to ask user to do something
{
this.waitStatus = WaitStatus.waiting;
this.getConfirmation.Invoke(text); // "calls" onGetConfirmation(string text);
// wait until user has finished and status is
// changed (by the UI thread) with Continue() method below.
while (this.waitStatus == WaitStatus.waiting)
{
Thread.Sleep(500);
}
// if user wanted to continue, do more stuff, otherwise thread is finished.
if (this.waitStatus == WaitStatus.canContinue)
{
...do more stuff
}
//UI thread is informed about thread finished here
}
}
public void Continue(bool continueTask)
{
if (continueTask)
this.waitStatus = WaitStatus.canContinue;
else
this.waitStatus = WaitStatus.stopRequested;
}
Here are some of the problems I face: The Question form is not fully modal dialog. It some times disappers and it can be found only under Alt-Tab (and then the mainform seems to be frozen since question form is not visible). This happens especially when I debug, but I'm worried that it might happen e.g. if you change windows. I've set the ShowInTask bar to false (since it is a dialog) and hence the dialog doesn't show in taskbar (and it shouldn't) but then there is no indication that it is under Alt-Tab. So somehow I think that the parent of the Question form is not being set correctly. Another problem is that I set the StartPosition to CenterParent, but the Question form always start from position 0,0 and I have to manually calculate the start position. So again, I think the parent form is not correct. Any ideas, what I'm doing wrong?
thank you!
Loading
Mike GoldPosted Aug 6, 2007, 4:19 PM
When you have a progress dialog running, as long as you have it in the GUI thread (Main Thread), you should be okay. However, a progress dialog (if running modally) is running in its own message pump. This will disallow the user from accessing the GUI while its running.
If you need feedback into the thread into the progress dialog, you should set up an event in your progress dialog that fires from the worker thread telling it the new value of the progress. You also have the option of calling form->Invoke (or BeginInvoke) from the worker thread directly on a delegate that sets the progress bar. Do not, however, set any gui component from the worker thread, because you'll get an exception for cross-thread violation.
Another strategy, if you don't want to have Alt-tab problems between the main dialog and the progress dialog is to put a progress bar directly in the status bar of the main form. You'll still need to Invoke from the worker thread into the status bar through a delegate, but it alleviates the problem of freezing the GUI with a modal dialog.