title: WPF Event: BitmapImage PropertyChanged: "Calling Thread Cannot access"
body: <p>I'm trying to understand what it is about the following code that <b>is</b> perfectly happy with loading a text file and displaying its contents, but <b>isn't</b> happy with loading a BitmapImage and displaying it on a timer.Elapsed event handler. </p>
  
  <p>I understand it has to do with the UI thread. </p>
  
  <p>But why is this not a problem for the textfile example?</p>
  
  <p>First, the XAML:</p>
  
  <pre><code>&lt;Window x:Class="WpfApplication7.Window1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Window1" Height="300" Width="300"&gt;
  
  &lt;StackPanel Orientation="Vertical"&gt;
  
  &lt;TextBlock Text="{Binding Path=Message, UpdateSourceTrigger=PropertyChanged}" FontSize="20" Height="40" Width="300"  Background="AliceBlue"  /&gt;
  
  &lt;Image Source="{Binding Path=Image,UpdateSourceTrigger=PropertyChanged}" Height="100" Width="100"/&gt;
  
  &lt;/StackPanel&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>and the C#, which raises a PropertyChangedEventHandler on a timer:</p>
  
  <pre><code>using System;
  using System.ComponentModel;
  using System.Timers;
  using System.Windows;
  using System.IO;
  using System.Windows.Threading;
  using System.Windows.Media.Imaging;
  </code></pre>
  
  <p>and</p>
  
  <pre><code>namespace WpfApplication7
  {
    public partial class Window1 : Window, INotifyPropertyChanged
    {
      public BitmapImage Image { get; private set; }
      public string Message { get; set; }
      public event PropertyChangedEventHandler PropertyChanged = delegate { };
  
      private Timer timer;
  
      public Window1()
      {
        InitializeComponent();
        this.DataContext = this;
  
        this.timer = new Timer { Enabled = true, Interval = 100 };
  
        this.timer.Elapsed += (s, e) =&gt;
        {
          //---happy loading from text file. UI updates :)
          this.Message = File.ReadAllText(@"c:\windows\win.ini").Substring(0, 20);
          PropertyChanged(this, new PropertyChangedEventArgs("Message"));
  
          //---not happy loading a BitmapImage. PropertyChanged unhappy :(
          // (Don't make me have to: ! )
          //Application.Current.Dispatcher.Invoke(
          //DispatcherPriority.Send, new Action(delegate
          //{
  
            this.Image = new BitmapImage(new Uri(@"C:\WINDOWS\Web\Wallpaper\Ascent.jpg"));
  
            //Edit --Ah hah, thanks Daniel ! 
            // DependencyObject-&gt; Freezable-&gt; Animatable-&gt; 
            // ImageSource-&gt; BitmapSource-&gt; BitmapImage
            this.Image.Freeze();  //&lt;--- this will fix it, no need for Dispatcher
  
            //Without Dispatcher or Freeze() ... right here:
            //"The calling thread cannot access this object because a different thread owns it."
            PropertyChanged(this, new PropertyChangedEventArgs("Image"));
          //}));
        };
      }
    }
  }
  </code></pre>
  
  <p>I know I can fix this with a "Application.Current.Dispatcher.Invoke". So fixing it isn't the problem. Not understanding why I should have to is the problem :)</p>
  
  <p><i>Similar</i> questions</p>
  
  <ul>
  <li><p><a href="https://stackoverflow.com/questions/36748/asynchronously-loading-a-bitmapimage-in-c-using-wpf">asynchronously loading a BitmapImage in C# using WPF</a></p></li>
  <li><p><a href="https://stackoverflow.com/questions/590590/making-sure-onpropertychanged-is-called-on-ui-thread-in-mvvm-wpf-app">Making sure OnPropertyChanged() is called on UI thread in MVVM WPF app</a></p></li>
  </ul>