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.
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.