• 解决.NET CF 3.5 Bitmap(Stream)未处理异常问题


    VS2008开发环境,在进行.NET CF 3.5下的WM Socket编程时

    Bitmap bmp = new Bitmap(Stream)处出现未处理异常

     (图片引自:http://www.cnblogs.com/fsyiyun/archive/2011/03/30/1999672.html) 

    通过摸索,我发觉无论对对象进行内存回收,这个问题依然存在。

    究其原因,个人猜测是Bitmap实例化时本身就会打开MemoryStream流,所以再用MemoryStream就很容易内存泄露

    因此强列建议,当和Bitmap一起合用时,用 FileStream或其它变通方法替代MemoryStream并及时内存回收

    以下是使用参考示例:

    主要功能是:拍照上传。

    View Code
    public class PhotoHelper
    {
    BaseForm _form; //拍照上传窗体
    TextBox _txtFileName; //显示照片路径
    PictureBox _picPhoto; //显示照片缩略图

    public PhotoHelper(BaseForm form,TextBox txtFileName,PictureBox picPhoto)
    {
    _form = form;
    _txtFileName = txtFileName;
    _picPhoto = picPhoto;
    _picPhoto.Image = new Bitmap(300, 350);

    }

           #region 拍照逻辑
    public void TakePhoto()
    {
    //拍照-----------------------------
    CameraCaptureDialog ccd = new CameraCaptureDialog();
    ccd.Mode = CameraCaptureMode.Still;
    ccd.Owner = _form;
    ccd.Title = "拍照";
    ccd.Resolution = new Size(1600, 1200);
    ccd.StillQuality = CameraCaptureStillQuality.Normal;

    if (ccd.ShowDialog() == DialogResult.OK)
    {
    //将拍好的以缩略图显示
    ImageChangedArgs args = new ImageChangedArgs(ccd.FileName);
    using (Graphics g = Graphics.FromImage(_picPhoto.Image))
    {

    g.DrawImage(args.Image,
    new Rectangle(0, 0, _picPhoto.Image.Width, _picPhoto.Image.Height),
    new Rectangle(0, 0, args.Image.Width, args.Image.Height),
    GraphicsUnit.Pixel);

    }
    args.Dispose();
    args = null;

    _txtFileName.Text = ccd.FileName;


    }
    ccd.Dispose();
    ccd = null;
    }
    #endregion
          #region 照片上传逻辑

    public void PhotoSave()
    {
    if (string.IsNullOrEmpty(_txtFileName.Text))
    {
    Global.ShowMsg("无照片可上传");
    return;
    }

    string prompt = "确认上传照片?";
    if (Global.ShowYesNoMsg(prompt) == DialogResult.No)
    return;


    //将照片转换为byte[]
    Byte[] b = FileToBytes(_txtFileName.Text);

    #region todo 将Byte[] 通过webservice上传服务器,在此请加入自己代码
    // CommandAndTaskIdObj commandObj = _form.CommandAndTaskIdObj;
    //WsRmsg msg = Global.GetService().UpFile(commandObj.UserName, commandObj.CommandId ,commandObj.TaskId , b, _txtFileName.Text);
    //if (msg.Flag == 0)
    //{
    // b = null;
    // throw new Exception(msg.Emsg);
    //}
    #endregion

    Global.ShowMsg("照片上传成功");


    _txtFileName.Text = string.Empty;
    b = null;

    }
    #endregion

    static byte[] FileToBytes(string sFilePath)
    {
    FileStream inFile = null;
    try
    {
    byte[] binaryData;
    inFile = new FileStream(sFilePath, FileMode.Open, FileAccess.Read);
    binaryData = new Byte[inFile.Length];
    long bytesRead = inFile.Read(binaryData, 0, (int)inFile.Length);
    return binaryData;
    }
    catch (Exception ex)
    {
    throw ex;
    }
    finally
    {
    if (inFile != null)
    {
    inFile.Close();
    inFile.Dispose();
    }
    inFile = null;
    }
    }


    internal void PhotoDispose()
    {
    throw new NotImplementedException();
    }
    }

    public class ImageChangedArgs : EventArgs, IDisposable
    {
    private Bitmap image;
    /// <summary>
    /// used to create the thumbnail
    /// </summary>
    private Stream stream;
    public ImageChangedArgs(string imageFilePath)
    {

    try
    {
    this.stream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read);
    this.image = new Bitmap(this.stream);
    }
    catch(Exception ex)
    {
    this.image = null;
    if (this.stream != null)
    {
    this.stream.Close();
    this.stream = null;
    }
    }
    }

    public Bitmap Image
    {
    get
    {
    return this.image;
    }
    }

    public Stream Stream
    {
    get
    {
    return this.stream;
    }
    }

    #region IDisposable Members

    public void Dispose()
    {
    if (this.image != null)
    this.image.Dispose();
    this.image = null;
    if (this.stream != null)
    {
    this.stream.Close();
    this.stream.Dispose();
    }
    this.stream = null;
    }

    #endregion
    }

    从上个例子可以看出,MemoryStream类基本上被FileStream替代。

    当加载大的图片时,只要内存允许,就不会报Exception异常 

    这是第二篇博客,如有错误请及时指出,欢迎留爪~~

  • 相关阅读:
    Java基础教程:多线程杂谈——双重检查锁与Volatile
    LeetCode:打印零与奇偶数【1116】
    Java基础教程:多线程基础(6)——信号量(Semaphore)
    LeetCode:交替打印【1115】
    做一件事情的3个关键指标:兴趣、能力和回报
    做一件事情的3个关键指标:兴趣、能力和回报
    Retry模式
    Java技术——String类为什么是不可变的
    2017战略No.2:开始电子化记账
    2017战略No.2:开始电子化记账
  • 原文地址:https://www.cnblogs.com/lindaWei/p/2324523.html
Copyright © 2020-2023  润新知