<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MultiBrowse" Height="600" Width="800" Loaded="OnLoaded">
<StackPanel Name="Stack" Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Button Content="New Window" Click="NewWindowHandler" />
<TextBox Name="newLocation" Width="500" />
<Button Content="GO!" Click="Browse" />
</StackPanel>
<Frame Name="placeHolder" Width="800" Height="550"></Frame>
</StackPanel>
</Window>
//File:Window.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Threading;
using System.Threading;
namespace WpfApplication1
{
public partial class Window1 : Window
{
public Window1() : base()
{
InitializeComponent();
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
placeHolder.Source = new Uri("http://www.kutayzorlu.com/java2s/com");
}
private void Browse(object sender, RoutedEventArgs e)
{
placeHolder.Source = new Uri(newLocation.Text);
}
private void NewWindowHandler(object sender, RoutedEventArgs e)
{
Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
newWindowThread.Start();
}
private void ThreadStartingPoint()
{
Window1 tempWindow = new Window1();
tempWindow.Show();
System.Windows.Threading.Dispatcher.Run();
}
}
}
Windows Presentation Foundation
Keep the UI from becoming non-responsive in single threaded application which performs a long operation.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Prime Numbers" Width="260" Height="75">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" >
<Button Content="Start" Click="StartOrStop" Name="startStopButton" Margin="5,0,5,0"/>
<TextBlock Margin="10,5,0,0">Number:</TextBlock>
<TextBlock Name="numberTextBlock" Margin="4,5,0,0">3</TextBlock>
</StackPanel>
</Window>
//File:Window.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Threading;
namespace WpfApplication1
{
public partial class Window1 : Window
{
public delegate void NextPrimeDelegate();
private long num = 1;
private bool continueCalculating = false;
public Window1() : base()
{
InitializeComponent();
}
public void StartOrStop(object sender, EventArgs e)
{
if (continueCalculating)
{
continueCalculating = false;
startStopButton.Content = "Resume";
}
else
{
continueCalculating = true;
startStopButton.Content = "Stop";
startStopButton.Dispatcher.BeginInvoke(DispatcherPriority.Normal,new NextPrimeDelegate(CheckNextNumber));
}
}
public void CheckNextNumber()
{
numberTextBlock.Text = num.ToString();
num += 2;
if (continueCalculating)
{
startStopButton.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.SystemIdle,
new NextPrimeDelegate(this.CheckNextNumber));
}
}
}
}
BlockThread.xaml
<Window x:Class="WPFThreading.BlockThread"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="UI Thread Blocker" Height="275" Width="225"
>
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Height" Value="20" />
<Setter Property="Background" Value="Beige"/>
<Setter Property="Margin" Value="2" />
</Style>
<Style TargetType="{x:Type Label}">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Margin" Value="2" />
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="2" />
</Style>
</Window.Resources>
<Border Width="200" Height="225" BorderBrush="Black"
BorderThickness="1" Margin="4">
<StackPanel>
<Label>Simulate Long-Running Process</Label>
<Button Name="button1" Click="button1_click">Go to sleep</Button>
<Label>Will I respond?</Label>
<Button Name="button2" Click="button2_click">Try Me</Button>
<Label>Output Messages</Label>
<TextBox Name="textbox1"/>
<Label/>
<StackPanel Orientation="Horizontal">
<Label>UI thread:</Label>
<Label Name="UIThreadLabel"></Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label>BG thread:</Label>
<Label Name="BackgroundThreadLabel"></Label>
</StackPanel>
</StackPanel>
</Border>
</Window>
//File:Window.xaml.cs
using System.Windows;
namespace WPFThreading
{
public partial class BlockThread : System.Windows.Window
{
public BlockThread()
{
InitializeComponent();
this.UIThreadLabel.Content = this.Dispatcher.Thread.ManagedThreadId;
this.BackgroundThreadLabel.Content = "N/A";
}
private void button1_click(object sender, RoutedEventArgs e)
{
System.Threading.Thread.Sleep(5000);
this.textbox1.Text = "Done Sleeping...";
}
private void button2_click(object sender, RoutedEventArgs e)
{
this.textbox1.Text = "Hello WPF";
}
}
}
ThreadPool.QueueUserWorkItem
<Window x:Class="DispatcherExamples.MyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Use BeginInvoke" Height="300" Width="300"
>
<Grid>
<StackPanel>
<Button x:Name="useBeginInvokeButton" Content="Use BeginInvoke" />
</StackPanel>
</Grid>
</Window>
//File:Window.xaml.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Threading;
namespace DispatcherExamples
{
public partial class MyWindow : System.Windows.Window
{
public MyWindow()
{
InitializeComponent();
useBeginInvokeButton.Click += new RoutedEventHandler(useBeginInvokeButton_Click);
}
void useBeginInvokeButton_Click(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem(delegate
{
MyDelegateType methodForUiThread = delegate
{
this.Background = new SolidColorBrush(Color.FromRgb(3,2, 1));
};
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, methodForUiThread);
});
}
public delegate void MyDelegateType();
}
}
Execute a Method Asynchronously Using the Dispatcher Queue
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF" Width="220" Height="104" >
<StackPanel Orientation="Vertical">
<Button Click="StartStop_Click" Name="btnStartStop">Start</Button>
<StackPanel Orientation="Horizontal">
<TextBlock>Biggest Prime Found:</TextBlock>
<TextBlock Name="txtNumber"/>
</StackPanel>
</StackPanel>
</Window>
//File:Window.xaml.cs
using System;
using System.Windows;
using System.Windows.Threading;
namespace WpfApplication1
{
public partial class Window1 : Window
{
private bool continueCalculating = false;
public Window1() : base()
{
InitializeComponent();
}
private void StartStop_Click(object sender, RoutedEventArgs e)
{
if(continueCalculating)
{
continueCalculating = false;
btnStartStop.Content = "Start";
}
else
{
continueCalculating = true;
btnStartStop.Content = "Stop";
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,new Action<int>(UpdateNumber), 3);
}
}
public void UpdateNumber(int current)
{
txtNumber.Text = current.ToString();
if(continueCalculating)
{
this.Dispatcher.BeginInvoke(DispatcherPriority.SystemIdle,new Action<int>(UpdateNumber), current + 2);
}
}
}
}
Ensure That You Are Running on the UI Thread
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF" Height="100" Width="300">
<StackPanel>
<Button Click="ButtonTrue_Click">UI Thread</Button>
<Button Click="ButtonFalse_Click">Non-UI Thread</Button>
</StackPanel>
</Window>
//File:Window.xaml.cs
using System.Windows;
namespace WpfApplication1
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void ButtonTrue_Click(object sender, RoutedEventArgs e)
{
this.Dispatcher.VerifyAccess();
}
private void ButtonFalse_Click(object sender, RoutedEventArgs e)
{
VerifyAccessDelegate del = new VerifyAccessDelegate(VerifyAccess);
del.BeginInvoke(null, null);
}
private delegate void VerifyAccessDelegate();
private void VerifyAccess()
{
this.Dispatcher.VerifyAccess();
}
}
}
Check Whether You Are Running on the UI Thread
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF" Height="120" Width="364">
<StackPanel>
<Button Click="ButtonTrue_Click">UI Thread</Button>
<Button Click="ButtonFalse_Click">Non-UI Thread</Button>
<TextBlock x:Name="txtResult"/>
</StackPanel>
</Window>
//File:Window.xaml.cs
using System.Windows;
using System.Windows.Threading;
namespace WpfApplication1
{
public partial class Window1 : Window
{
private delegate void CheckAccessDelegate();
private delegate void SetResultTextDelegate(string result);
public Window1()
{
InitializeComponent();
}
private void ButtonTrue_Click(object sender, RoutedEventArgs e)
{
CheckAccess();
}
private void ButtonFalse_Click(object sender, RoutedEventArgs e)
{
CheckAccessDelegate del = new CheckAccessDelegate(CheckAccess);
del.BeginInvoke(null, null);
}
private void CheckAccess()
{
if(txtResult.Dispatcher.CheckAccess())
{
txtResult.Text = "True";
}else{
txtResult.Dispatcher.BeginInvoke(DispatcherPriority.Normal,new SetResultTextDelegate(SetResultText),"False");
}
}
private void SetResultText(string result)
{
txtResult.Text = result;
}
}
}