WPF 的Image 控件 设置 Image.Source 的数据源,可能存在跨线程调用的问题。

相信很多WPF 的开发,应该都很多用到 Image 这个控件来显示图片。这个图片的来源可以来自各种各样的方式获取到。

我们的组内白板、批注的扫码的功能也用到这个去生成二维码,生成后,二维码显示不出来,由于触发到了全局捕获,界面又没有崩溃,遇到了好几个坑,记录一下。

开始看代码:

    private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        ImageSource imageSource = null;

        //用来模拟时间回调后,去获取图片资源
        Task.Run(() =>
        {
             imageSource = BitmapImageToBitmap();
        });

        await Task.Delay(2000);
        MyImage.Source = imageSource;

    }

    public static BitmapImage BitmapImageToBitmap()
    {
        BitmapImage bitmapImage = new BitmapImage(new Uri(@"C:\Users\a\Desktop\祁厅长壁纸.png", UriKind.RelativeOrAbsolute));
        return bitmapImage;
    }

我们在工作线程上去获取ImageSource (模拟事件回调),然后在Loaded 事件中给 Image控件的Source 赋值。

 

其实细看一下ImageSource 的定义,是继承了 Animatable,而Animatable继承了Freezable,Animatable继承了Freezable,Freezable继承了DependencyObject

  这也就是说,ImageSource  的创建和使用必须是同一个线程下的,不然就会存在以上的异常报错

Freezable.Freeze Method (System.Windows) | Microsoft Learn

解决方法:

BitmapImage 在获取图片的时候,提供了Freenze()的方法
public static BitmapImage BitmapImageToBitmap()
{
    BitmapImage bitmapImage = new BitmapImage(new Uri(@"C:\Users\a\Desktop\祁厅长壁纸.png", UriKind.RelativeOrAbsolute));

    if (bitmapImage.CanFreeze)
    {
        bitmapImage.Freeze();
    }

    return bitmapImage;
}

加上就可以正常显示了,效果如下:

 

posted @ 2024-09-28 12:59  wuty007  阅读(92)  评论(0编辑  收藏  举报