gpt4 book ai didi

.net - WPF 可以/是否有多个 GUI 线程?

转载 作者:行者123 更新时间:2023-12-03 08:41:34 26 4
gpt4 key购买 nike

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

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

顺便说一句:我知道我需要使用 Dispatcher为此目的提出反对。所以,我可以改写我的问题并问:是否总是只有一个 Dispatcher WPF 中所有 GUI 元素的对象?

最佳答案

根据第一个答案中的链接,我自己做了一些验证。我想在这里分享结果。首先:

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

然而:

简单地创建一个新窗口(模式或非模式)不会创建一个新的 GUI 线程。 需要显式创建线程(通过创建 Thread 的新实例)。

注意:模态对话框可能不是使用单独的线程,而是通过使用 Dispatcher.PushFrame() 来实现。这会阻止此方法的调用者,同时仍允许分派(dispatch)事件。

我创建了一个简单的 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");
}
}));
}
}
}

关于.net - WPF 可以/是否有多个 GUI 线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5716804/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com