尝试调用Invoke方法会在w​​inform应用程序中引发异常

时间:2018-06-14 13:50:12

标签: c# multithreading winforms thread-safety

我有一个遗留项目(Visual Studio 2003),它是由其他人过去制作的,现在我需要维护它。此遗留应用程序使用Windows消息队列与另一个应用程序通信。一个队列用于receive,queueInput,另一个用于send,queueOutput。

有一个分为六个步骤的动作。在执行操作时,winform中会显示进度,比如说MyFrm。

因此,通过实例化winform然后从其load事件开始操作,第一步通过线程启动:

MyFrm frm = new MyFrm(param1, param2);
frm.ShowDialog();

加载事件:

private void MyFrm_Load(object sender, System.EventArgs e)
{
    Thread th = new Thread(new ThreadStart(BeginFirstStep));
    th.Start();
}

然后创建一些线程并以级联方式执行:

private void BeginFirstStep()
{
   // Do some stuff
   Invoke(new ThreadStart(FirstStepCompleted));
}

private void FirstStepCompleted()
{
    myLabel1.Visible = true;

   // Do some other stuff
   Thread th = new Thread(new ThreadStart(BeginSecondStep));
   th.Start();
}

private void BeginSecondStep()
{
  // Do some stuff
  Invoke(new ThreadStart(SecondStepCompleted));
}

private void SecondStepCompleted()
{
    label3.enabled = false;
    // Do some other stuff
    if (some_condition)
    {
         ThirdSteepCompleted();
         return;
    }
    else if (some_other_condition)
    {
        Thread th = new Thread(new ThreadStart(Do_AnotherTask));
        th.Start();
    }
    else
    {
       Do_AnotherTask2();
    }
}

private MessageQueue queueInput;
private MessageQueue queueOutput;

private void Do_AnotherTask2(object state)
{
    if(InvokeRequired)
    {
        Invoke(new TimerCallback(Do_AnotherTask2), new object[]{state});
    }
    else
    {
        queueOutput = new MessageQueue(@".\Private$\Actions");
        queueInput = MessageQueue.Create(@".\Private$\Response");

        queueInput.ReceiveCompleted += new ReceiveCompletedEventHandler(queueInput_ReceiveCompleted);
        queueInput.BeginReceive();

        queueOutput.Send(BuildMsgToSend());
    }

}

从另一个winform应用程序中,响应将添加到此队列,然后添加到事件中 引发了queueInput_ReceiveCompleted:

private void queueInput_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
     // Do some stuff with data received
     Invoke(new ThreadStart(ThirdStepCompleted)); // HERE IT SOMETIMES CRASHES (NOT ALWAYS).
}

private void ThirdStepCompleted()
{
        // Do some other stuff
        Thread th = new Thread(new ThreadStart(BeginFourthStep));
        th.Start();
}

等等......其余步骤。

问题是:

有时(并非总是),程序在执行Invoke时在queueInput_ReceiveCompleted处理程序方法中崩溃。错误说:

  

System.InvalidOperationException:无法调用Invoke或InvokeAsync   控件,直到创建窗口句柄。

我知道,这是一个复杂而难以理解的代码,但它是按原样设计的....

0 个答案:

没有答案