主窗口代码如下:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Thread thread = new Thread( () => { NewWindow win = new NewWindow(); win.MainWindow = this; win.Show(); System.Windows.Threading.Dispatcher.Run(); }); thread.SetApartmentState(ApartmentState.STA); thread.IsBackground = true; thread.Start(); list = new List<BitmapImage>(); list.Add(new BitmapImage(new Uri("image.png", UriKind.Relative))); } public List<BitmapImage> list; }
子窗口UI及代码:
UI
<Window x:Class="A.NewWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="NewWindow" Height="300" Width="300"> <Grid> <Image x:Name="image" HorizontalAlignment="Left" Height="128" Margin="85,27,0,0" VerticalAlignment="Top" Width="128"/> <Button Content="Button" HorizontalAlignment="Left" Height="40" Margin="96,191,0,0" VerticalAlignment="Top" Width="117" Click="Button_Click"/> </Grid> </Window>
后台
public partial class NewWindow : Window { public NewWindow() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { Application.Current.Dispatcher.Invoke( new Action( () => { image.Source = MainWindow.list[0]; })); } public MainWindow MainWindow { get; set; } }
点击子窗口Button按钮后报错:
image.Source = MainWindow.list[0]; 调用线程无法访问此对象,因为另一个线程拥有该对象。
求高手解答,怎么才能在点击按钮后将图片显示在子窗口中
private void button1_Click(object sender, RoutedEventArgs e)
{
MainWindow.Dispatcher.Invoke((Action)(() => {
MainWindow.ImageList[0].Freeze();
}));
image.Source = new ImageBrush( MainWindow.ImageList[0]);
}
BitmapImage 调用Freeze()后就可以跨线程使用了。
另外设置Image.Source也要在Image所在的线程上,楼主提供的代码image所在的线程的Dispatcher不等于
Application.Current.Dispatcher。
应该直接在button事件中设置image.Source,不能通过Application.Current.Dispatcher。
@德年: 谢谢帮忙解决问题。
能帮忙顺便解释下原理吗?
什么样的资源可以在跨线程中使用?
为什么值类型的在使用的时候没有报跨线程异常?是因为值类型引用的是原始的副本的原因吗?
还是说对于那些在内存中不可变的,例如字符串类型的对象,在跨线程操作时不用担心其变化?
还请帮忙解答。
@SystemUser:
https://msdn.microsoft.com/zh-cn/library/system.windows.threading.dispatcher.aspx
里面的备注有讲到Dispatcher与Freezable对象,能解答你的问题。
@德年: 非常感谢!又学到了新的东西了