पहले उत्तर में दिए गए लिंक के आधार पर मैंने अपने आप पर कुछ सत्यापन किया था। मैं यहां परिणाम साझा करना चाहता हूं। सबसे पहले:
कई जीयूआई थ्रेड (और कई Dispatcher
उदाहरणों के लिए) हो सकते हैं।
हालांकि:
, बस एक नई विंडो (मोडल या नहीं) बनाने एक नया जीयूआई सूत्र नहीं बनाया है। किसी को धागे को स्पष्ट रूप से बनाने की आवश्यकता है (Thread
का नया उदाहरण बनाकर)।
नोट: इसके बजाय अलग धागे का उपयोग करने का, मोडल संवाद की संभावना Dispatcher.PushFrame() जो ब्लॉक इस विधि के फोन करने वाले, जबकि अभी भी घटनाओं की इजाजत दी भेज दिया उपयोग करके एहसास हुआ जा रहा है।
मैंने इन सभी चीजों को सत्यापित करने के लिए एक सरल 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");
}
}));
}
}
}
स्रोत
2011-04-28 12:39:41
आप WPF सूत्रण मॉडल प्रलेखन पढ़े हैं? http://msdn.microsoft.com/en-us/library/ms741870.aspx –