【发布时间】:2014-08-13 22:16:49
【问题描述】:
我注意到 MessageBox 何时为模态时似乎存在不一致的行为。
首先,从 UI 线程启动一个 MessageBox。正如预期的那样,这会产生一个模态消息框:
void MainThreadClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello!");
}
接下来,从后台线程启动。这会产生一个无模式消息框,我假设是因为它不在 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 线程上调用的,那为什么它不像前面的例子那样是 Modal 的呢?
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.SynchronizingObject,这让我想知道......
标签: wpf modal-dialog messagebox background-thread