我们在一个窗口调用MessageBox.Show方法会在,该窗口制造出一个模态的消息框。但是有小伙伴最近问我他发现这个消息框经常会到窗口下面显示。


出现问题

我们来看下他的代码,很简单完全没有问题是不是

但是在实际运行中,其中的一个方法Foo抛出了一个异常。

而作为代码书写者,为了确保软件的正常运行,将这个方法的所有异常都吞掉了。

此时导致的结果就是,用户端看到软件运行正常,但是没有期望的输出

        public MainWindow()
        {
            InitializeComponent();
            Loaded += (sender, args) =>
            {
                MessageBox.Show("黄腾霄好瘦哟");
            };
        }

1563249113514

我们稍稍做一些改动,让messagebox延迟一点点出现。然后我们在主窗口显示后立刻点击其他程序窗口

        public MainWindow()
        {
            InitializeComponent();
            Loaded += async (sender, args) =>
            {
                await Task.Delay(3000);
                MessageBox.Show("黄腾霄好瘦哟");
            };
        }

惊这个messagebox掉下去了。

1563249361961

Why

有小伙伴会问,这个是一个时机问题么?

额,不完全是。这个其实是跟点击其他程序窗口这一操作有关。其实你只要启动时点击其他窗口的手速够快,也能出现。

我们看看MessageBox的源码。当我们采用MessageBox.Show方法重载不带有owner参数时,他会通过GetActiveWindow这个方法获取当前激活的窗口,作为owner。而我们通过只要在程序执行到这里之前点击其他程序窗口,就会出现上述问题

1563249678194

How

怎么改就很简单了,我们主动将owner传入,就再也不会出现上述问题了

例如我们在Barcatch块中添加一些日志输出,会发现这些输出出现在FirstChanceException的输出之后

        public MainWindow()
        {
            InitializeComponent();
            Loaded += async (sender, args) =>
            {
                await Task.Delay(3000);
                MessageBox.Show(this, "黄腾霄好瘦哟");
            };
        }

参考链接:


本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/%E5%A6%82%E4%BD%95%E5%88%A9%E7%94%A8c-%E6%89%BE%E5%88%B0%E7%89%A9%E7%90%86%E7%BD%91%E5%8D%A1%E7%9A%84Mac%E5%9C%B0%E5%9D%80.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名黄腾霄(包含链接: https://xinyuehtx.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系