2012-04-20 86 views
1

我只想在另一个线程中更改窗口的背景。有两个程序,一个是工作正确的,另一个抛出InvalidOperationException。使用由其他线程创建的对象

权代码:

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

的错误代码:

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)); 
    } 
} 

不同,这些代码之间是,错误代码创建的子线程的图像刷对象。 所以我的问题是:在wpf程序中,线程是否只能使用由自己的线程创建的对象? 感谢您的任何答复。

回答

1

是的,你是对的。只有UI线程可以使用它创建的对象。因此,您可以使用Dispatcher将UI操作“排入”其正确的线程。

回答你的第二个问题,当然,有一种方法可以将对象“传递”到UI线程。如果你看到的BeginInvoke结构(调度员),它是:

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

凡ARGS是params对象数组,还有就是你把PARAMS。

现在,如果您使用的是一些Freezable对象(例如某些图像,画笔,变换或几何体),那么在将其发送到UI线程之前,您需要object.Freeze();

+0

如果UI线程只能使用自己创建的对象,是否有任何方法让其他线程通过对象到UI线程? – adream307 2012-04-21 06:17:51

+0

@ adream307当然有,请参阅我的编辑:) – 2012-04-21 14:28:46

0

是的,正确的,它不仅是关于WPF,但一般来说,关于Windows programming

您无法从与其自己不同的其他线程更新UI对象。

造成这种情况的原因很简单,因为必须保证消息泵送以及特别是交付到操作系统的目标控制。这对于使用SendMesage进行通信当然是有效的,但对于PostMessage也是如此。

0

如果你在一个单独的线程上创建一个对象,你可以在gui线程上使用它,如果你先冻结它。见Freezable objects