我有一个遗留项目(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 控件,直到创建窗口句柄。
我知道,这是一个复杂而难以理解的代码,但它是按原样设计的....