C# 从以Form1为父级的异步线程调用MessageBox
单击位于C# 从以Form1为父级的异步线程调用MessageBox,c#,winforms,multithreading,C#,Winforms,Multithreading,单击位于表单1上的按钮1后,程序将检查新版本是否可用(通过互联网),但在新线程中执行此操作(在检查期间不会冻结表单)。 无论是否找到新版本,都会显示相应的MessageBox,但它没有父级(因为它是从线程调用的,而不是直接从form1调用的) 如何使MessageBox以form1作为父项显示 this.Invoke(new Action(() => { MessageBox.Show(this, "text"); })); 这将切换到主线程并显示带有form1父级的MessageBox
表单1
上的按钮1
后,程序将检查新版本是否可用(通过互联网),但在新线程中执行此操作(在检查期间不会冻结表单)。无论是否找到新版本,都会显示相应的
MessageBox
,但它没有父级(因为它是从线程调用的,而不是直接从form1
调用的)
如何使MessageBox
以form1
作为父项显示
this.Invoke(new Action(() => { MessageBox.Show(this, "text"); }));
这将切换到主线程并显示带有form1
父级的MessageBox。尝试使用
if ( Form1.InvokeRequired ) {
Form1.Invoke((Action)delegate{MessageBox.Show(Form1,"Hello");});
}
虽然所选答案提供了一种从异步线程显示
MessageBox
的好方法,但它不处理您希望从显示的特定MessageBox
检索对话框结果的情况
如果要从显示在窗体顶部的调用的消息框
返回对话框结果
。然后您需要使用委托而不是操作
委托
Action
代理始终返回void,而Func
具有返回值
下面是我设计的一个小方法来处理这个特定场景:
private DialogResult BackgroundThreadMessageBox(IWin32Window owner, string text)
{
if (this.InvokeRequired)
{
return (DialogResult) this.Invoke(new Func<DialogResult>(
() => { return MessageBox.Show(owner, text); }));
}
else
{
return MessageBox.Show(owner, text);
}
}
private DialogResult BackgroundThreadMessageBox(iwin32窗口所有者,字符串文本)
{
if(this.invokererequired)
{
返回(DialogResult)this.Invoke(新函数(
()=>{returnmessagebox.Show(owner,text);});
}
其他的
{
返回MessageBox.Show(所有者,文本);
}
}
虽然这通常不被认为是最佳实践或设计,但在紧要关头它会起作用。在我的情况下,我在另一个班级,有一个文本框的参考,所以我使用了下面的代码:
_txtResultado.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate ()
{
MessageBox.Show("My message!");
}));
这会给我带来很多编译错误(即错误1关键字“This”在静态属性、静态方法或静态字段初始值设定项中无效),而不是This
use form1的实例如何在此处获得DialogResult?Invoke返回一个对象,该对象为空。@StealthRabbi:请看我对该特定场景的回答。出于好奇,什么是更好的实践/设计?在这种情况下,由于MessageBox
始终是从另一个线程调用的,因此使用if(Form1.InvokeRequired)
在这里是无用的。如果始终是,请同意
_txtResultado.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate ()
{
MessageBox.Show("My message!");
}));