14

我通过 ThreadPool.QueueUserWorkItem 启动一个线程,其中有一个消息框对话框:

System.Windows.Forms.DialogResult dr = System.Windows.Forms.MessageBox.Show("您想在后台下载升级吗?..", "升级可用", MessageBoxButtons.YesNo);

它似乎工作正常,但是在一些客户建议他们没有收到消息弹出后,我有点怀疑。我在 .NET 框架 2.0+ 中感觉您不需要编组这个特定的调用,它会为您完成。正确的?

这是一个感兴趣的半相关主题: 为什么在 MessageBox.Show 中使用所有者窗口?

4

4 回答 4

20

不,它不会编组到 UI 线程。如果你想一想,它就不可能这样做。

一个应用程序中可能有多个 UI 线程。某些程序,例如 Internet Explorer,有许多 UI 线程。.Show 调用会选择哪个 UI 线程?

也可以在没有 UI 线程的应用程序中使用 MessageBox.Show。您可以在控制台应用程序中很好地调用它,它会起作用。

MessageBox.Show 将在调用它的线程上显示 UI。如果线程上还没有运行消息泵,它将设置一个临时的以便运行。Show 调用完成后,它将将其拆除。

于 2009-02-18T06:19:27.820 回答
11

作为一般规则,您不应该在主/应用程序线程之外进行 GUI 工作。我会在可以执行调用的父窗体上创建一个 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);

但也要记住:调试多线程 GUI 应用程序时,并且您在主/应用程序线程以外的线程中进行调试,您需要关闭“启用属性评估和其他隐式函数调用”选项,或者否则 VS 将自动从当前线程中获取本地/全局 GUI 对象的值,这将导致您的应用程序以奇怪的方式崩溃/失败。转到工具->选项->调试以关闭该设置。

对上限感到抱歉,但这花了我几天的时间来弄清楚为什么我每次尝试调试我的应用程序都会挂起然后崩溃。

于 2009-02-18T04:33:36.327 回答
5

好吧,我会编组并指定一个窗口,只要这样MessageBox才能获得正确的焦点。可能他们根本看不到它,因为它位于您的一种表单后面,并且不知道它应该在前台。

于 2009-02-17T23:48:51.813 回答
0

这是应用程序还是服务。如果它是一项服务,则可能没有设置“允许与桌面交互”权限。

在服务控制面板小程序中查看服务的属性。

于 2009-02-17T23:51:13.603 回答