互联网断开后图像控制卡住了

时间:2013-06-07 09:19:09

标签: wpf image

我在WPF窗口中有一个图像控件,其xmls如下:

  <Image Source="{Binding Path=ImageUrl,Converter={StaticResource ImageSourceConverter}}"
        Height="150" HorizontalAlignment="Left" Margin="100,15,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="200" />

在运行时,我通过更改有界属性的值来更改Image的源。此代码在正常情况下工作正常。仅在断开互联网连接后才会出现问题如果在下载图像时断开连接,则不显示图像。没关系。但是当互联网回来并且图像源被更改为另一个图像URL时,图像不会被下载。甚至没有调用ImageConverter。在此之后,无法在控件中显示图像。图像控制卡住了。

public class ImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string url;
        try
        {
            if (value is string)
                url = (string)value;
            else
                url = ((Uri)value).AbsolutePath;
        }
        catch (Exception)
        {

            url = string.Empty;
            return value;
        }

        BitmapImage src = new BitmapImage();
        if (targetType == typeof(ImageSource))
        {
            if (value is string)
            {
                string str = (string)value;



                src.BeginInit();
                src.CacheOption = BitmapCacheOption.OnLoad;
                src.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                src.UriSource = new Uri(str, UriKind.RelativeOrAbsolute);
                src.EndInit();
                return src;

            }
            else if (value is Uri)
            {
                Uri uri = (Uri)value;
                return new BitmapImage(uri);
            }
        }
        return value;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

任何帮助都将受到高度赞赏。

2 个答案:

答案 0 :(得分:0)

关于内存泄漏的article讨论了使用下载的BitmapImage作为图像源引起的泄漏[7]:

引用:“此漏洞被触发,因为WPF不会删除在Web下载期间使用的某些对象(如LateBoundBitmapDecoder,BitmapFrameDecode等)的内部引用,并导致泄漏。

只有从互联网下载图像时才会发生此泄漏。 (例如,从本地计算机加载图像时不会出现)“

...

修复/解决方法

解决方法是考虑首先以其他方式将BitmapImage下载到临时文件夹或内存,然后使用本地BitmapImage。 (参见WebClient.DownloadFile&amp; WebClient.DownloadData API)

也许你会接近。

答案 1 :(得分:0)

我首先通过下载图像解决了问题,如果成功,则仅将其分配给Image控件。如果有人需要,请在此处发布。

private bool ValidImage(string url, out BitmapImage image)
    {
        try
        {
            System.Net.WebRequest request = System.Net.WebRequest.Create(url);
            System.Net.WebResponse response = request.GetResponse();
            System.IO.Stream responseStream = response.GetResponseStream();
            Bitmap bitmap = new Bitmap();
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, ImageFormat.Png);

                stream.Position = 0;
                BitmapImage result = new BitmapImage();
                result.BeginInit();
                // According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
                // Force the bitmap to load right now so we can dispose the stream.
                result.CacheOption = BitmapCacheOption.OnLoad;
                result.StreamSource = stream;
                result.EndInit();
                result.Freeze();
                image = result;
            }

        }
        catch (Exception ex)
        {
            logger.Error(ex, "error downlading image");
            image = null;
            return false;
        }

        return true;
    }