Hi

 

A while ago Shahar wrote an article about whether WPF Data Binding is Thread safe. Shahar’s findings were that Even if you change a property from a different thread the PropertyChanged event will be called on the UI Thread making Binding Thread Safe.

I have created a Window with 2 TextBlocks, one of them is binded to a Dependency Property and the other is binded to a regular property:

The Window:

   1: <StackPanel>
   2:     <TextBlock Text="{Binding DpTxt}" Width="100" Margin="5"></TextBlock>
   3:     <TextBlock Text="{Binding Txt}" Width="100" Margin="5"></TextBlock>
   4:     <Button Content="Change Text" Margin="5" Click="Button_Click"></Button>
   5: </StackPanel>

The Code Behind:

   1: public partial class Window1 : Window, INotifyPropertyChanged
   2: {
   3:     public string DpTxt
   4:     {
   5:         get { return (string)GetValue(DpTxtProperty); }
   6:         set { SetValue(DpTxtProperty, value); }
   7:     }
   8:  
   9:     // Using a DependencyProperty as the backing store for DpTxt.  
  10:     // This enables animation, styling, binding, etc...
  11:     public static readonly DependencyProperty DpTxtProperty =
  12:         DependencyProperty.Register("DpTxt", typeof(string), typeof(Window1),
  13:                                     new UIPropertyMetadata("Nothing"));
  14:  
  15:     private string TxtProperty = "Nothing";
  16:  
  17:     public string Txt
  18:     {
  19:         get { return TxtProperty; }
  20:         set
  21:         {
  22:             TxtProperty = value;
  23:             PropertyChanged(this, new PropertyChangedEventArgs("Txt"));
  24:         }
  25:     }
  26:  
  27:     public Window1()
  28:     {
  29:         InitializeComponent();
  30:         this.DataContext = this;
  31:     }
  32:  
  33:     #region INotifyPropertyChanged Members
  34:  
  35:     public event PropertyChangedEventHandler PropertyChanged;
  36:  
  37:     #endregion
  38:  
  39:     private void Button_Click(object sender, RoutedEventArgs e)
  40:     {
  41:         Thread t = new Thread(new ThreadStart(test));
  42:         t.Start();
  43:     }
  44:  
  45:     private void test()
  46:     {
  47:         Txt = "Changes";
  48:         DpTxt = "Changes";
  49:     }
  50: }

As you can see Clicking the Button creates a Thread that changes both Properties.

 

And now the results!

 

If you read Shahar’s post you know that the regular Property works, but on the Dependency Property we get the following Exception:

Dependency Property Exception

It does not work!

 

Dependency Properties are not thread safe, but why?

 

If we look at the syntax of the Dependency Property declaration we see that we pass 4 parameters Name, Type, OWNER and Initial Value. I have specified the Window as the owner which means that to the Framework, this Dependency Property is the same as any Button, TextBlock or any other UI Element which is Owned by the UI Thread. By Trying to change it from the Thread it was as if I was trying to change the UI itself.

 

So always remember, a Dependency property is a UI element as far as Threading goes

 

Amit

Tags :

Post a Comment