1
Answer

How to open a form from non-UI thread?

Janne

Janne

17y
4.9k
1
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!

Answers (1)