WPF是否可以有多个GUI线程?

编程入门 行业动态 更新时间:2024-10-12 03:26:27
本文介绍了WPF是否可以有多个GUI线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

WPF是否可以有多个GUI线程?还是总是只有一个GUI线程(即使我有多个Windows/对话框)?

Can/Does WPF have multiple GUI threads? Or does it always only have one GUI thread (even if I have multiple windows/dialogs)?

我之所以问是因为我有来自其他线程的事件,并且我想在GUI线程中处理它们(因为我需要根据事件来修改主窗口的控件).

I'm asking because I have events coming from other threads and I'd like to handle them in the GUI thread (because I need to modify the controls of my main window accordings to the events).

顺便说一句:我知道我需要为此使用Dispatcher对象.因此,我可以重新提问一下:WPF中的所有GUI元素始终只有一个Dispatcher对象吗?

Btw: I know I need to use a Dispatcher object for this purpose. So, I could rephrase my question and ask: Is there always only one Dispatcher object for all GUI elements in WPF?

推荐答案

基于第一个答案中的链接,我自己进行了一些验证.我想在这里分享结果.首先:

Based on the link in the first answer I did some verification on my own. I'd like to share the results here. First of all:

可以有多个GUI线程(因此有多个Dispatcher实例).

There can be multiple GUI threads (and therefor multiple Dispatcher instances).

但是:

仅创建一个新窗口(是否有模式)不会创建一个新的GUI线程.一个人需要显式创建该线程(通过创建一个新的Thread).

Simply creating a new window (modal or not) does not create a new GUI thread. One needs to create the thread explicitly (by creating a new instance of Thread).

注意:代替使用单独的线程,模态对话框很可能通过使用 Dispatcher.PushFrame()会阻止此方法的调用方,同时仍允许分派事件.

Note: Instead of using separate threads, modal dialogs are likely being realized by using Dispatcher.PushFrame() which blocks the caller of this method while still allowing events to be dispatched.

我创建了一个简单的WPF类(同样,基于第一个答案的链接)来验证所有这些内容.我在这里分享它,以便您可以尝试一下.

I've created a simple WPF class (again, based on the link from the first answer) to verify all this stuff. I share it here so you can play around with it a little bit.

MainWindow.xaml:

MainWindow.xaml:

<Window x:Class="WindowThreadingTest.MainWindow" xmlns="schemas.microsoft/winfx/2006/xaml/presentation" xmlns:x="schemas.microsoft/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:

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"); } })); } } }

更多推荐

WPF是否可以有多个GUI线程?

本文发布于:2023-11-12 13:17:36,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1581615.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多个   线程   WPF   GUI

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!