WPF可以/是否有多个GUI线程?或者它总是只有一个GUI线程(即使我有多个窗口/对话框)?我问是因为我有来自其他线程的事件,我想在GUI线程中处理它们(因为我需要根据事件修改主窗口的控件)。顺便说一句:我知道我需要使用Dispatcher对象来实现这个目的。所以,我可以换个方式问:在WPF中所有的GUI元素总是只有一个Dispatcher对象吗?
Dispatcher
7vhp5slm1#
基于http://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/,我自己做了一些验证。我想在这里分享结果。首先:
可以有多个GUI线程(因此可以有多个Dispatcher示例)。
然而:
*简单地创建一个新窗口(模式或非模式) 不会 * 创建一个新的GUI线程。**需要显式地创建线程(通过创建Thread的新示例)。
Thread
我创建了一个简单的WPF类(同样,基于第一个答案的链接)来验证所有这些东西。我把它分享在这里,这样你就可以玩一点。MainWindow.xaml:
<Window x:Class="WindowThreadingTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="250" Height="130"> <StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="Thread's ID is "/> <TextBlock x:Name="m_threadId"/> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="Thread's threading apartment is "/> <TextBlock x:Name="m_threadTA"/> </StackPanel> <Button Click="OnCreateNewWindow" Content="Open New Window"/> <Button Click="OnAccessTest" Content="Access Test"/> </StackPanel> </Window>
MainWindow.xaml.cs:
using System; using System.Threading; using System.Windows; using System.Windows.Media; namespace WindowThreadingTest { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private static uint s_windowNumber = 0; private readonly MainWindow m_prevWindow; public MainWindow() : this(null) { } public MainWindow(MainWindow prevWindow) { InitializeComponent(); this.m_prevWindow = prevWindow; this.Title = String.Format("Window {0}", ++s_windowNumber); Thread thread = Thread.CurrentThread; this.m_threadId.Text = thread.ManagedThreadId.ToString(); this.m_threadTA.Text = thread.GetApartmentState().ToString(); } private void OnCreateNewWindow(object sender, RoutedEventArgs e) { CreateNewWindow(true, false, true); } private void CreateNewWindow(bool newThread, bool modal, bool showInTaskbar) { MainWindow mw = this; if (newThread) { Thread thread = new Thread(() => { MainWindow w = new MainWindow(this); w.ShowInTaskbar = showInTaskbar; if (modal) { // ShowDialog automatically starts the event queue for the new windows in the new thread. The window isn't // modal though. w.ShowDialog(); } else { w.Show(); w.Closed += (sender2, e2) => w.Dispatcher.InvokeShutdown(); System.Windows.Threading.Dispatcher.Run(); } }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } else { MainWindow w = new MainWindow(this); w.ShowInTaskbar = showInTaskbar; if (modal) { // Even modal dialogs run in the same thread. w.ShowDialog(); } else { w.Show(); } } } private void OnAccessTest(object sender, RoutedEventArgs e) { if (m_prevWindow == null) { return; } this.Background = Brushes.Lavender; try { m_prevWindow.Background = Brushes.LightBlue; } catch (InvalidOperationException excpt) { MessageBox.Show("Exception: " + excpt.Message, "Invalid Operation"); } m_prevWindow.Dispatcher.Invoke((Action)(() => m_prevWindow.Background = Brushes.Green)); this.Dispatcher.Invoke((Action)(() => { try { m_prevWindow.Background = Brushes.Red; } catch (InvalidOperationException excpt) { MessageBox.Show("Exception: " + excpt.Message, "Invalid Dispatcher Operation"); } })); } } }
1条答案
按热度按时间7vhp5slm1#
基于http://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/,我自己做了一些验证。我想在这里分享结果。首先:
可以有多个GUI线程(因此可以有多个
Dispatcher
示例)。然而:
*简单地创建一个新窗口(模式或非模式) 不会 * 创建一个新的GUI线程。**需要显式地创建线程(通过创建
Thread
的新示例)。我创建了一个简单的WPF类(同样,基于第一个答案的链接)来验证所有这些东西。我把它分享在这里,这样你就可以玩一点。
MainWindow.xaml:
MainWindow.xaml.cs: