【问题标题】:Why it always throws an ObjectDisposedException?为什么它总是抛出 ObjectDisposedException?
【发布时间】:2013-05-30 18:54:54
【问题描述】:

由于windows phone不能处理gif,我写了一个小方法,但是好像有点错误。
下面的代码在运行到(JPG和PNG部分)bitimg.SetSource(e.Result)时总是抛出异常;
正如它所说,这是否意味着我不能使用 e.Result 因为它已被处置?但是怎么会这样呢,方法还没有停止,编译器为什么要dispose呢?

为什么以及如何解决?

错误信息:

{System.ObjectDisposedException:无法访问已处置的对象。 对象名称:“MS.Internal.InternalMemoryStream”。在 MS.Internal.InternalMemoryStream.Seek(Int64 偏移量,SeekOrigin 原点) 在 ImageTools.IO.Gif.GifDecoder.Decode(扩展图像图像,流 流)在 xicihutong.ViewModel.RichTextBoxBindingBehavior.c__DisplayClass7.b__4(Object s, OpenReadCompletedEventArgs e) 在 System.Net.WebClient.OnOpenReadCompleted(OpenReadCompletedEventArgs e) 在 System.Net.WebClient.OpenReadOperationCompleted(Object arg)}

image.Loaded += (s1, e1) =>
{
    WebClient wc = new WebClient();
    wc.AllowReadStreamBuffering = true;
    wc.OpenReadCompleted += (s, e) =>
    {
        if (e.Error == null && !e.Cancelled)
        {
            //Check the type of the Image
            ImageTypeCheck.ImageType incomingIMGType = ImageTypeCheck.getImageType(e.Result);

            BitmapImage bitimg = new BitmapImage();
            bitimg.CreateOptions = BitmapCreateOptions.BackgroundCreation;

            switch (incomingIMGType)
            {
                //handle GIF for windows phone
                case ImageTypeCheck.ImageType.Gif:
                    Decoders.AddDecoder<GifDecoder>();
                    Encoders.AddEncoder<JpegEncoder>();
                    GifDecoder gif = new GifDecoder();
                    JpegEncoder jpg = new JpegEncoder();
                    ImageTools.ExtendedImage extImg = new ImageTools.ExtendedImage();
                    gif.Decode(extImg, e.Result);
                    using (MemoryStream stream = new MemoryStream())
                    {
                        jpg.Encode(extImg, stream);
                        bitimg.SetSource(stream);
                        image.Source = bitimg;
                    }
                    break;
                case ImageTypeCheck.ImageType.Bmp:
                case ImageTypeCheck.ImageType.Null:
                    break;
                case ImageTypeCheck.ImageType.Jpg:
                case ImageTypeCheck.ImageType.Png:
                    try
                    {
                        bitimg.SetSource(e.Result);
                        image.Source = bitimg;
                    }
                    catch (Exception ex)
                    {
                        App.print(ex.Message);
                    }
                    break;
            }
        }
    };
    wc.OpenReadAsync(new Uri(item, UriKind.Absolute), wc);

}

===================================

using System.IO;

namespace xicihutong.DataServiceAgent
{
    class ImageTypeCheck
    {
        /// <summary>
        /// define
        /// </summary>
        public enum ImageType
        {
            Null,Png,Jpg,Gif,Bmp
        }


        public static ImageType getImageType(Stream stream)
        {
            ImageType type = ImageType.Null;

            byte[] header = new byte[8];
            stream.Read(header, 0, 8);

            //Check if PNG then do something;
            //Check if JPG then do something;
            //Check if GIF then do something;

            stream.Close();

            return type;
        }
    }
}

【问题讨论】:

  • GifDecoder 和 JpegEncoder 是从哪里来的?
  • 我知道这与答案无关。但是你为什么不让你的代码更具可读性呢?这肯定会帮助人们做出贡献而不是跳过。
  • @JustinNiessner 他们是 ImageTools 的辅助方法
  • @AlbertGao 你能显示ImageTypeCheck.getImageType 方法的代码吗?这个方法似乎很可能正在关闭流。
  • @nair 抱歉,已编辑!

标签: c# windows-phone-7 exception webclient objectdisposedexception


【解决方案1】:

正如您指出的那样,ImageTypeCheck.getImageType 方法正在关闭流。

您应该如何找到问题?

  1. 错误消息清楚地表明流已被释放。剩下的就是找到罪魁祸首了。
  2. 调用堆栈显示在引发错误时正在调用ImageTools.IO.Gif.GifDecoder.Decode。所以它发生在这之前。
  3. 幸运的是,只有一种方法使用 GifDecoder 之前的流,那就是ImageTypeCheck.getImageType

要解决此问题,只需从 ImageTypeCheck.getImageType 方法中删除 stream.Close,并将其替换为 Seek 即可返回到流的开头(GifDecoder 期望流位于开头图片)。

stream.Seek(0, SeekOrigin.Begin);

【讨论】:

  • 你是我的英雄,我只是评论那行并且出现了一个新错误,请使用你的建议来修复它。实在是太感谢你了,明天老板不会怪我的:P
  • 再挖一点,所以是不是说每次我使用一个流时,除非我关闭流或者使用Seek方法来设置,否则流的Position会被改变并保存。如果你不关闭或寻找,下一个读取流的人将从之前的位置开始?
猜你喜欢
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 2017-09-08
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 2020-08-18
相关资源
最近更新 更多