Wpf 来自后台线程的模态Messagebox

Wpf 来自后台线程的模态Messagebox,wpf,modal-dialog,messagebox,background-thread,Wpf,Modal Dialog,Messagebox,Background Thread,我注意到,当MessageBox处于模态状态时,似乎存在不一致的行为 首先,从UI线程启动MessageBox。这将产生一个模态MessageBox,如预期的那样: void MainThreadClick(object sender, RoutedEventArgs e) { MessageBox.Show("Hello!"); } 接下来,从后台线程启动。我想这会导致一个无模式的MessageBox,因为它不在UI线程上 void WorkerThreadC

我注意到,当MessageBox处于模态状态时,似乎存在不一致的行为

首先,从UI线程启动MessageBox。这将产生一个模态MessageBox,如预期的那样:

void MainThreadClick(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("Hello!");
    }
接下来,从后台线程启动。我想这会导致一个无模式的MessageBox,因为它不在UI线程上

void WorkerThreadClick(object sender, RoutedEventArgs e)
    {
        ThreadPool.QueueUserWorkItem((x) =>
        {
            MessageBox.Show("Hello!");
        });
    }
接下来,从后台线程启动,但被调度到UI线程,会导致它再次处于模态:

void WorkerThreadClick(object sender, RoutedEventArgs e)
    {
        ThreadPool.QueueUserWorkItem((x) =>
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                MessageBox.Show("Hello!");
            });
        });
    }
最后,这是一个奇怪的例子,与上面类似,但是使用FileSystemWatcher线程会导致一个无模式对话框。这是为什么。。。它是在UI线程上调用的,为什么不像前面的示例那样是模态的呢

public MainWindow()
    {
        InitializeComponent();

        m_watcher = new FileSystemWatcher()
        {
            Path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
            NotifyFilter = NotifyFilters.LastWrite,
            IncludeSubdirectories = true,
            Filter = "*.*"
        };

        m_watcher.Changed += OnFileSystemResourceChanged;
        m_watcher.EnableRaisingEvents = true;
    }

    void OnFileSystemResourceChanged(object _sender, FileSystemEventArgs _args)
    {
        Application.Current.Dispatcher.Invoke(() =>
        {
            MessageBox.Show("Hello!");
        });
    }
虽然我可以使用MessagBox.Show()方法解决最后一个问题,该方法将窗口所有者作为参数,但我想了解发生了什么


为什么最后两个例子中的行为有所不同?

这个问题确实困扰了我一段时间。在做一些分析后,我发现在最后一个案例中(
FileSystemWatcher
),所有者发生了变化(我还没有计算出谁接管了所有权)

我还发现有一个微小但重要的区别

在场景2中

void WorkerThreadClick(object sender, RoutedEventArgs e)
{
    ThreadPool.QueueUserWorkItem((x) =>
    {
        MessageBox.Show("Hello!");
    });
}
即使当我关闭
main窗口时,行为是无模式的,我的应用程序也会关闭

FileSystemWatcher
场景中,行为再次是无模式的,但当我关闭
main窗口时,应用程序不会关闭,除非我关闭
MessageBox
(因此我知道有人接管了所有权。我还不知道是谁接管了它)

编辑

在上一个场景中,我更改了
关闭
模式

void OnFileSystemResourceChanged(object sender, FileSystemEventArgs args)
    {
        Application.Current.Dispatcher.Invoke(() =>
            {
                Application.Current.ShutdownMode=ShutdownMode.OnMainWindowClose;
                MessageBox.Show("Test");
            });
    }

即使在关闭
主窗口时
我的
应用程序
也不会关闭,除非
消息框
关闭。我尝试查找所有者,但随后出现空引用异常。

问得好。我正在查看
FileSystemWatcher.SynchronizingObject
,这让我想知道…谢谢你的回复,看起来我无法得到答案:(