C# 遗留应用程序在非ui线程中创建对话框
我在一个遗留应用程序上工作了一段时间,发现了一点问题。该系统是一个极其复杂的客户机/服务器,具有标准和自定义框架 应用程序中内置的自定义框架之一涉及验证工作流操作。它发现潜在的错误,将它们分为警告和错误,并将结果传递回客户端。警告和错误之间的主要区别在于警告询问用户是否希望忽略错误 我遇到的问题是,此提示符的对话框是在非ui线程上创建的,因此,当显示该对话框时,我们会遇到跨线程问题。我试图调用对话框的显示,但是由于尚未创建窗口句柄,因此失败。(InvokeRequired返回false,我认为在本例中这意味着它在父树中找不到合适的句柄,而不是它不需要它。)C# 遗留应用程序在非ui线程中创建对话框,c#,multithreading,C#,Multithreading,我在一个遗留应用程序上工作了一段时间,发现了一点问题。该系统是一个极其复杂的客户机/服务器,具有标准和自定义框架 应用程序中内置的自定义框架之一涉及验证工作流操作。它发现潜在的错误,将它们分为警告和错误,并将结果传递回客户端。警告和错误之间的主要区别在于警告询问用户是否希望忽略错误 我遇到的问题是,此提示符的对话框是在非ui线程上创建的,因此,当显示该对话框时,我们会遇到跨线程问题。我试图调用对话框的显示,但是由于尚未创建窗口句柄,因此失败。(InvokeRequired返回false,我认为在
有人对我如何创建此对话框并让UI线程设置并调用它有什么建议吗?我不完全清楚实现的细节,但下面的代码是如何处理从非UI线程到UI线程的调用。此代码段假定“This”对象是windows窗体,表示ui线程 其思想是,非ui线程调用名为“ShowMessageBox”的方法,该方法位于ui线程上。当调用发生时,请检查ui线程上的对象所需的this.invokererequired,在本例中,该对象是windows窗体。invokererequired将返回“true”,这将导致执行if语句第一部分中的代码。此代码通过创建与“ShowMessageBox”方法具有相同签名的委托并重新传递发送方对象和事件参数,从主ui线程调用ShowMessageBox函数,实际上将非ui线程调用编组到ui线程。随后对“ShowMessageBox”方法的调用现在被“封送”到ui线程,并将绕过if的第一部分,移动到else,在那里您可以调用messagebox或表单或任何您需要的东西 享受吧
private object _lock = new object(); //should have class scope
private void ShowMessageBox(object sender, EventArgs e)
{
if (this.InvokeRequired)
{
lock (_lock)
{
EventHandler d = new EventHandler(ShowMessageBox);
this.Invoke(d, new object[] { sender, e });
return;
}
}
else
{
MessageBox.Show("Show some messsage or invoke your form instance.");
}
}
在创建控件之后。通过访问其句柄属性强制创建句柄:
sync = new System.Windows.Forms.Control();
var temp = sync.Handle;
然后你就可以调用它了:
sync.Invoke((Action)(() => { }));
正如我前面提到的,在这种情况下,这不起作用。如果没有窗口句柄,则无法调用invoke。您是否考虑过上述模式并创建自定义EventArgs类,该类将传递消息或枚举类型,然后您可以使用该类从if语句的else部分中创建相应的表单实例。这将避免在非ui线程上创建表单的问题。您只需要传递某种类型的指示符或消息,然后从ui线程对该消息执行操作,而不是尝试从创建表单实例的线程以外的线程调用表单实例。这可能值得一试,尽管这相当复杂。代码相当可怕。我会再考虑一下的,谢谢。