C# MessageBox.Show() 是否自动编组到 UI 线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/559252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does MessageBox.Show() automatically marshall to the UI Thread?
提问by
I launch a thread via ThreadPool.QueueUserWorkItem which has a messagebox dialogue in it:
我通过 ThreadPool.QueueUserWorkItem 启动一个线程,其中有一个消息框对话框:
System.Windows.Forms.DialogResult dr = System.Windows.Forms.MessageBox.Show("would you like to download upgrade in background? ..", "Upgrade Available", MessageBoxButtons.YesNo);
System.Windows.Forms.DialogResult dr = System.Windows.Forms.MessageBox.Show("你想在后台下载升级吗?..", "升级可用", MessageBoxButtons.YesNo);
It seems to work fine however I am a little suspicious after some customers suggested they were not getting the message popping up. I had the feeling in .NET framework 2.0+ you do not need to marshal this particular call, it does it for you. Correct?
它似乎工作正常,但是在一些客户建议他们没有收到消息弹出后,我有点怀疑。我在 .NET 框架 2.0+ 中感觉你不需要编组这个特定的调用,它会为你完成。正确的?
This is a semi-related topic for interest: Why use a owner window in MessageBox.Show?
这是一个感兴趣的半相关主题: 为什么在 MessageBox.Show 中使用所有者窗口?
回答by Marc Gravell
Well, I would marshal and specify a window, if only so the MessageBox
can get the correct focus. It might be they simply can't see it because it is behind one of your forms, and doesn't know it should be in the foreground.
好吧,我会编组并指定一个窗口,只要这样MessageBox
可以获得正确的焦点。可能是他们根本看不到它,因为它在您的一个表单后面,并且不知道它应该在前台。
回答by Scott Langham
Is this an application or a service. If it's a service, maybe it's not set up with the 'Allow interaction with desktop' permission.
这是应用程序还是服务。如果它是一项服务,则可能没有设置“允许与桌面交互”权限。
See the properties of the service in the services control panel applet.
在服务控制面板小程序中查看服务的属性。
回答by PhilChuang
As a general rule, you shouldn't do GUI work outside of the main/application thread. I'd make a ShowMessageBox method on the parent form that can do an Invoke:
作为一般规则,您不应在主/应用程序线程之外执行 GUI 工作。我会在可以执行 Invoke 的父窗体上创建一个 ShowMessageBox 方法:
public DialogResult ShowMessageBox (String message, String caption)
{
if (this.InvokeRequired) {
return (DialogResult) this.Invoke (new PassStringStringReturnDialogResultDelegate (ShowMessageBox), message, caption);
}
return MessageBox.Show (this, message, caption);
}
public delegate DialogResult PassStringStringReturnDialogResultDelegate (String s1, String s2);
BUT ALSO KEEP IN MIND: when debugging a multi-threaded GUI app, and you're debugging in a thread other than the main/application thread, YOU NEED TO TURN OFF the "Enable property evaluation and other implicit function calls" option, or else VS will automatically fetch the values of local/global GUI objects FROM THE CURRENT THREAD, which will cause your application to crash/fail in strange ways. Go to Tools->Options->Debugging to turn that setting off.
但还要记住:在调试多线程 GUI 应用程序时,并且您在主/应用程序线程以外的线程中调试时,您需要关闭“启用属性评估和其他隐式函数调用”选项,或者否则 VS 将自动从当前线程中获取本地/全局 GUI 对象的值,这将导致您的应用程序以奇怪的方式崩溃/失败。转到工具->选项->调试以关闭该设置。
Sorry for the caps, but this took me DAYS to figure out why I every time I tried debugging my app it would hang and then crash.
对不起,我花了几天时间才弄清楚为什么我每次尝试调试我的应用程序时它都会挂起然后崩溃。
回答by JaredPar
No, it doesn't Marshal to the UI thread. If you think about it, it wouldn't be possible for it to do so.
不,它不会编组到 UI 线程。如果你仔细想想,它是不可能这样做的。
It's possible to have more than one UI thread in an application. Some programs, such as internet explorer, have many UI threads. Which UI thread would the .Show call pick?
一个应用程序中可能有多个 UI 线程。某些程序,例如 Internet Explorer,有许多 UI 线程。.Show 调用会选择哪个 UI 线程?
It's also possible to use MessageBox.Show in an application that has no UI threads. You can very well call this in a Console application and it will work.
也可以在没有 UI 线程的应用程序中使用 MessageBox.Show。您可以在控制台应用程序中很好地调用它,它会起作用。
MessageBox.Show will show UI on the thread it is called from. If there isn't already a message pump running on the thread it will setup a temporary one in order to function. It will tear it down after the Show call completes.
MessageBox.Show 将在调用它的线程上显示 UI。如果线程上还没有消息泵在运行,它将设置一个临时的以便正常运行。它将在 Show 调用完成后将其拆除。