控件中国网现已改版,您看到的是老版本网站的镜像,系统正在为您跳转到新网站首页,请稍候.......
中国最专业的商业控件资讯网产品咨询电话:023-67870900 023-67871946
产品咨询EMAIL:SALES@COMPONENTCN.COM

Com Excel组件释放资源关闭进程总结

作者:未知 出处:cnblog 2013年05月13日 阅读:

C#如何释放非托管资源
.NET 平台在内存管理方面提供了GC(Garbage Collection),负责自动释放托管资源和内存回收的工作,但它无法对非托管资源进行释放,这时我们必须自己提供方法来释放对象内分配的非托管资源,比如你在对象的实现代码中使用了一个COM对象。Microsoft.Office.Interop.Excel就属于一个COM对象,因此由它生成的所有资源都是非团管资源。
 
根据MSDN上的描述:为适当释放非托管资源,建议您实现公共的 Dispose 或 Close 方法,这两个方法可为对象执行必要的清理代码操作。 IDisposable 接口为实现接口的资源类提供 Dispose 方法。 因为 Dispose 方法是公共的,所以应用程序用户可以直接调用该方法来释放非托管资源占用的内存。使用 Dispose 方法主要在使用本机资源的托管对象和向 .NET framework 公开 COM 对象。
 
链接:http://msdn.microsoft.com/zh-cn/library/498928w2.aspx
 
using语句
using的功能有:引入命名空间,为命名空间或类型创建别名。
 
using 语句还的一个作用是允许程序员指定使用资源的对象应当何时释放资源。为 using 语句提供的对象必须实现 IDisposable 接口。此接口提供了 Dispose 方法,该方法将释放此对象的资源。
 
使用规则:
 
  a)   using语句只能用于实现了IDisposable接口的类型,禁止为不支持IDisposable接口类型使用using语句,否则会出现编译错误
 
b)   using语句适用于清理单个非托管资源的情况,而多个非托管对象的清理最好以try-finaly来实现,因为嵌套using语句可能存在隐藏的Bug.内层using块引发异常时,将不能释放外层using块的对象资源。
 
using实质:
 
  在程序编译阶段,编译器会自动将using语句生成try-finally语句,并在finally块中调用对象的Dispose方法,来清理资源.所以,using语句等效于try-finally语句。
 
封装Excel操作类
综上我们可以封装一个Excel操作类,继承IDispose接口,实现Dispose方法释放Excel生成的所有非托管资源,最后由GC回收,在声明该类对象的时候用using(ExcelHelper excel=new ExcelHelper ()){  }。
 
using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using Microsoft.Office.Interop.Excel;
 using System.Runtime.InteropServices;
 
 namespace ClassLibrary1
 {
     public  class ExcelHelper :IDisposable
     {
         #region 变量
         private Application _application ;
         private Workbook _workbook;
         private Worksheet _worksheet;
         private Range _range;
         #endregion
 
        
         /// <summary>
         /// 构造函数
         /// </summary>
         public ExcelHelper()
         {
             this._application = new Application();
             this._workbook = this._application.Workbooks.Add(Type.Missing);
             this._worksheet = (Worksheet)_workbook.Sheets.get_Item(1); 
         }
         /// <summary>
         /// 创建Excel返回路径?
         /// </summary>
         /// <returns></returns>
         public string  CreateExcel(bool isSleep=true)
         {
           
             _worksheet.Cells[1, 5] = "项目质量计划";
             _range = (Range)_worksheet.get_Range("B1","L1");
             _range.Merge(0);
             _range = (Range)_worksheet.Cells[1, 5];
             _range.EntireColumn.AutoFit();
             //throw new Exception();
             string filePath = AppDomain.CurrentDomain.BaseDirectory.ToString() + "QualityPlan\\Files";
             if (!System.IO.Directory.Exists(filePath))
             {
                 System.IO.Directory.CreateDirectory(filePath);
             }
             string FullName = "质量计划导出模板" +  DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".xls";
             string filefullpath = filePath + "\\" + FullName;
             _application.ActiveWorkbook.SaveAs(filefullpath, Microsoft.Office.Interop.Excel.XlFileFormat.xlExcel12, null, null, false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, null, null, null, null);
             return filefullpath;
         }
 
         /// <summary>
         /// 释放资源,IDispose接口
         /// </summary>
         public void Dispose()
         {
             if (_workbook != null)
                 _workbook.Close(null, null, null);
             if (_application != null)
             {
                 _application.Workbooks.Close();
                 _application.Quit();
             }
             if (_range != null)
             {
                 System.Runtime.InteropServices.Marshal.ReleaseComObject(_range);
                 _range = null;
             }
 
             if (_worksheet != null)
             {
                 System.Runtime.InteropServices.Marshal.ReleaseComObject(_worksheet);
                 _worksheet = null;
             }
             if (_workbook != null)
             {
                 System.Runtime.InteropServices.Marshal.ReleaseComObject(_workbook);
                 _workbook = null;
             }
             if (_application != null)
             {
                 System.Runtime.InteropServices.Marshal.ReleaseComObject(_application);
                 _application = null;
             }
             GC.Collect();
         }
     }
 
    
 }
using (ExcelHelper excelHelper = new ExcelHelper())
       {
            string filefullpath = excelHelper.CreateExcel();
        }
以上方法在本机测试通过,但是用Microsoft.Office.Interop.Excel遇到大并发操作可能会出现等待问题,经测试当用户A占着Excel进程生成Excel文件时,用户B也点击导出Excel,此时就会出现B等待的状态,直到A 释放Excel资源。
 

热推产品

  • ActiveReport... 强大的.NET报表设计、浏览、打印、转换控件,可以同时用于WindowsForms谀坔攀戀Forms平台下......
  • AnyChart AnyChart使你可以创建出绚丽的交互式的Flash和HTML5的图表和仪表控件。可以用于仪表盘的创......
首页 | 新闻中心 | 产品中心 | 技术文档 | 友情连接 | 关于磐岩 | 技术支持中心 | 联系我们 | 帮助中心 Copyright-2006 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 电话:023 - 67870900 传真:023 - 67870270 产品咨询:sales@componentcn.com 渝ICP备12000264号 法律顾问:元炳律师事务所 重庆市江北区塔坪36号维丰创意绿苑A座28-5 邮编:400020
在线客服
在线客服系统
在线客服
在线客服系统