1

I just want to change the window's background in another thread. there are two program, one is work right, and the other throw an InvalidOperationException.

The right code:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Thread t = new Thread(new ParameterizedThreadStart(threadTest));
        t.Start(@"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg");
    }

    void threadTest(object obj)
    {
        string path = obj as string;
        this.Dispatcher.Invoke(new Func<object>(() => this.Background = new 
    }
}

the Error Code:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Thread t = new Thread(new ParameterizedThreadStart(threadTest));
        t.Start(@"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg");
    }

    void threadTest(object obj)
    {
        string path = obj as string;
        //this.Dispatcher.Invoke(new Func<object>(() => this.Background = new ImageBrush(new BitmapImage(new Uri(path)))));
        ImageBrush background = new ImageBrush(new BitmapImage(new Uri(path)));
        this.Dispatcher.Invoke(new Func<object>(() => this.Background = background));
    }
}

the different between these codes is that, the error code create the ImageBrush object in the child thread. So my question is that: in the wpf program, is the thread can only use the objects creates by own thread? thanks for any reply.

H.B.
  • 166,899
  • 29
  • 327
  • 400
adream307
  • 95
  • 1
  • 7

3 Answers3

1

Yes, you are right. Only the UI thread can use objects created by it. So, you can use the Dispatcher to "enqueue" the UI operations on it's proper thread.

Answering your second question, sure, there's a way to "pass" objects to the UI Thread. If you see the BeginInvoke structure (of the Dispatcher) it's:

public DispatcherOperation BeginInvoke(
    Delegate d,
    params Object[] args
)

Where the args is the params object array, there's where you put the params.

Now, if you are using some Freezable object (for example some Image, Brush, Transform or Geometry) then you need to object.Freeze(); before send it to the UI Thread.

Erre Efe
  • 15,387
  • 10
  • 45
  • 77
  • If the UI thread can only use the objects which created by itself, is there any method let the other threads past the object to the UI thread? – adream307 Apr 21 '12 at 06:17
0

Yes, correct, It's not only about WPF, but in general, about Windows programming.

You can not update UI object from other thread different from its own.

The reason for this is simply because, the message pumping and especially delivery to destination control of OS must be guaranteed. This is naturally valid for communication using SendMesage, but for PostMessage too.

Tigran
  • 61,654
  • 8
  • 86
  • 123
0

If You create an object on a separate thread, You might use it on gui thread if You freeze it first. See Freezable objects.

erikH
  • 2,286
  • 1
  • 17
  • 19