wfo*_*orl 5 wpf modal-dialog messagebox background-thread
我注意到当 MessageBox 处于模式状态时,行为似乎不一致。
首先,从 UI 线程启动 MessageBox。这会产生一个模态 MessageBox,正如预期的那样:
void MainThreadClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello!");
}
Run Code Online (Sandbox Code Playgroud)
接下来,从后台线程启动。这会导致无模式 MessageBox,我猜是因为它不在 UI 线程上?
void WorkerThreadClick(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem((x) =>
{
MessageBox.Show("Hello!");
});
}
Run Code Online (Sandbox Code Playgroud)
接下来,从后台线程启动,但分派到 UI 线程,导致它再次成为模态:
void WorkerThreadClick(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem((x) =>
{
Application.Current.Dispatcher.Invoke(() =>
{
MessageBox.Show("Hello!");
});
});
}
Run Code Online (Sandbox Code Playgroud)
最后,这是一个奇怪的问题,与上面类似,但使用 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!");
});
}
Run Code Online (Sandbox Code Playgroud)
虽然我可以使用以 Window 所有者作为参数的 MessagBox.Show() 方法解决最后一个问题,但我想了解发生了什么。
为什么最后两个示例的行为不同?
这个问题确实困扰了我一段时间。经过一些分析,我发现在最后一种情况(FileSystemWatcher)中,所有者发生了变化(我还没有弄清楚谁接管了所有权)。
我还发现存在一个微小但重要的差异。
在场景 2 中
void WorkerThreadClick(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem((x) =>
{
MessageBox.Show("Hello!");
});
}
Run Code Online (Sandbox Code Playgroud)
即使当我关闭我MainWindow的应用程序时,行为是无模式的,我的应用程序也会关闭。
在这种FileSystemWatcher情况下,行为再次是无模式的,但是当我关闭MainWindow应用程序时,除非我关闭应用程序,否则应用程序不会关闭MessageBox(所以我知道有人已经接管了所有权。谁接管了它,我还不知道)。
编辑
我改变了Shutdown最后一个场景的模式
void OnFileSystemResourceChanged(object sender, FileSystemEventArgs args)
{
Application.Current.Dispatcher.Invoke(() =>
{
Application.Current.ShutdownMode=ShutdownMode.OnMainWindowClose;
MessageBox.Show("Test");
});
}
Run Code Online (Sandbox Code Playgroud)
即使这样,当我关闭时,除非关闭,否则MainWindow我的不会关闭。我尝试找到所有者,但随后出现空引用异常。ApplicationMessageBox
| 归档时间: |
|
| 查看次数: |
1379 次 |
| 最近记录: |