在前几天写到的Silverlight 操作Excel 中的进程资源释放问题 中,存在很多不完善的地方,因为在BeforeClose中处理掉Excel资源,会造成Excel无法再进行与代码的部分控制进行交互了。

于是,继续谷歌……发现一篇很不错的文章,其Demo的效果也正是我想要的,于是,Mark一下。

原文是日语的,借助翻译还是能看懂吧:(

原问题的地址是:How to release COM objects in Silverlight 4,作者地址:http://csfun.blog49.fc2.com/blog-entry-79.html (好像要用代理才能看),Demo下载地址:SilverOffice。

以下是根据我个人的理解,翻译并整理的两个关键的类。

1、ComObjectWrapper,实现IDisposable接口

 1  public class ComObjectWrapper : IDisposable
 2     {
 3         /// <summary>
 4         /// Com对象被释放时的事件
 5         /// </summary>
 6         internal event EventHandler ComObjectDisposed;
 7
 8         //对象是否被释放
 9         private Boolean _disposed = false;
10
11         /// <summary>
12         /// Com对象集合
13         /// </summary>
14         private List<ComObjectWrapper> _children = new List<ComObjectWrapper>();
15
16         /// <summary>
17         /// Com对象是否被释放的的标记
18         /// true情况下释放出来
19         /// </summary>
20         public Boolean Disposed
21         {
22             get
23             {
24                 return _disposed;
25             }
26         }
27
28         /// <summary>
29         /// 增加对象到集合,并为对象绑定释放事件
30         /// </summary>
31         /// <param name="child"></param>
32         protected void AddChildren(ComObjectWrapper child)
33         {
34             _children.Add(child);
35             child.ComObjectDisposed += new EventHandler(child_ComObjectDisposed);
36         }
37
38         /// <summary>
39         /// 子对象被释放时在集合移除
40         /// </summary>
41         /// <param name="sender"></param>
42         /// <param name="e"></param>
43         private void child_ComObjectDisposed(object sender, EventArgs e)
44         {
45             _children.Remove(sender as ComObjectWrapper);
46         }
47
48         /// <summary>
49         /// 释放Com对象(集合所有对象)
50         /// </summary>
51         private void ReleaseChildren()
52         {
53             foreach (ComObjectWrapper child in _children)
54             {
55                 child.ComObjectDisposed -= new EventHandler(child_ComObjectDisposed);
56                 child.Dispose();
57             }
58
59             _children.Clear();
60         }
61
62         /// <summary>
63         /// 执行释放资源(虚函数)
64         /// </summary>
65         protected virtual void DoDispose() { }
66
67         #region IDisposable Members
68
69         /// <summary>
70         /// 释放Excel程序资源
71         /// </summary>
72         public void Dispose()
73         {
74             try
75             {
76                 //释放对象
77                 ReleaseChildren();
78
79                 DoDispose();
80
81                 _disposed = true;
82
83                 if (ComObjectDisposed != null)
84                 {
85                     ComObjectDisposed(this, EventArgs.Empty);
86                 }
87             }
88             catch { }
89         }
90
91         #endregion
92     }

2、InstanceManager类,对所有Excel的Com对象进行管理

 1  public class InstanceManager
 2     {
 3         /// <summary>
 4         /// Excel对象实例集合
 5         /// </summary>
 6         private static List<ComObjectWrapper> _excelApplications = new List<ComObjectWrapper>();
 7
 8         /// <summary>
 9         /// 新增一个Excel对象
10         /// </summary>
11         /// <returns></returns>
12         public static ExcelApplication CreateAppication()
13         {
14             //自动化功能是否可用
15             if (!AutomationFactory.IsAvailable) return null;
16
17             dynamic excelObject = AutomationFactory.CreateObject("Excel.Application");
18
19             ExcelApplication application = new ExcelApplication(excelObject);
20             _excelApplications.Add(application);
21             application.ComObjectDisposed += new System.EventHandler(application_ComObjectDisposed);
22             return application;
23         }
24
25         /// <summary>
26         /// Com对象被释放时的事件
27         /// </summary>
28         /// <param name="sender"></param>
29         /// <param name="e"></param>
30         static void application_ComObjectDisposed(object sender, System.EventArgs e)
31         {
32             try
33             {
34                 _excelApplications.Remove(sender as ComObjectWrapper);
35             }
36             catch { }
37         }
38
39         /// <summary>
40         /// 取得已经运行的Excel进程实例。
41         /// </summary>
42         /// <param name="create"></param>
43         /// <returns></returns>
44         public static ExcelApplication GetApplication(bool create)
45         {
46             //自动化功能是否可用
47             if (!AutomationFactory.IsAvailable) return null;
48
49             dynamic excelObject = null;
50
51             //在已经生成的com对象集合中取得没有被释放的实例
52             foreach (ExcelApplication excel in _excelApplications)
53             {
54                 if (!excel.Disposed)
55                 {
56                     return excel;
57                 }
58             }
59
60             try
61             {
62                 excelObject = AutomationFactory.GetObject("Excel.Application");
63             }
64             catch
65             {
66                 if (create)
67                 {
68                     excelObject = AutomationFactory.CreateObject("Excel.Application");
69                 }
70             }
71
72             if (excelObject != null)
73             {
74                 ExcelApplication application = new ExcelApplication(excelObject);
75                 _excelApplications.Add(application);
76                 application.ComObjectDisposed += new System.EventHandler(application_ComObjectDisposed);
77                 return application;
78             }
79             else
80             {
81                 return null;
82             }
83         }
84
85         /// <summary>
86         /// 释放所有Excel进程
87         /// </summary>
88         public static void ReleaseAll()
89         {
90             foreach (ComObjectWrapper wrapper in _excelApplications)
91             {
92                 wrapper.ComObjectDisposed -= new EventHandler(application_ComObjectDisposed);
93                 wrapper.Dispose();
94             }
95             _excelApplications.Clear();
96         }
97     }

使用时,在ExcelApplication的封装类进行调用Exit()函数即可。

注意,封装类要进行继续1中的ComObjectWrapper类, 并重写DoDispose。封装类的代码就不上了,百度或者谷歌都有:(

public class ExcelApplication : ComObjectWrapper
{/// <summary>   /// Excel程序退出/// </summary>public void Exit(){_excel.Quit();Dispose();}/// <summary>/// Com对象的释放处理/// </summary>protected override void DoDispose(){try{Workbooks.Close();Workbooks.Dispose();_excel.Quit();((IDisposable)_excel).Dispose();_excel = null;}catch { }}//other code ...........
} 

public class ExcelWorkbook : ComObjectWrapper{
   protected override void DoDispose(){try{((IDisposable)workBook).Dispose();}catch { }}
//.................other code }

11月27日补充:

在手动new一个Excel封装类的变量后(如:ExcelWorkSheet、ExcelRange),一定要记得把它手动释放进程,不然会直到程序关闭才自动释放!

 var currentSheet = new ExcelWorkSheet {WorkSheet = workBook.WorkBook.ActiveSheet};
// other code to do something
currentSheet.Dispose();

转载于:https://www.cnblogs.com/oneivan/archive/2012/11/26/2789302.html

Silverlight 操作Excel 中的进程资源释放问题(续)相关推荐

  1. python 操作 excel 百度网盘 资源下载_批量读取excel百度链接转存到自己的百度网盘...

    [Python] 纯文本查看 复制代码#!/usr/local/Cellar/python/3.7.1/bin # -*- coding: UTF-8 -*- import requests,re,t ...

  2. 关于使用QAxObject类操作Excel中出现QAxBase : Error calling IDispatch member SaveAs:Exception thrown by server解决

    前段时间在使用QAxObject对数据库文件导出为Excel中遇到了QAxBase : Error calling IDispatch member SaveAs:Exception thrown b ...

  3. qt中关闭窗口资源释放问题

    针对QDialog对象,如果是栈上分配的,就不存在资源泄漏问题,但是当对象是new出来的,并且以局部对像存在,当关闭时,窗口只是隐藏,资源是没有释放的,每次exec后者需要delete来释放,另外一种 ...

  4. notebook中kiil进程从而释放显存的方法

    import ospid = os.getpid() !kill -9 $pid

  5. Java操作Excel中HSSFCell.CELL_TYPE_STRING、BOOLEAN、NUMERIC无定义解决方法

    错误原因:jar包版本更新,官方改动: 解决方法: 导入CellType包import org.apache.poi.ss.usermodel.CellType 使用CellType.STRING代替 ...

  6. JXL(JXLS)的使用:java中操作Excel的解决方案之一。

    摘要: 本文讲述的是如何使用开源项目JXSL来对Excel及其内部的数据进行操作,本人整理汇总自网络. JXLS项目主页: http://sourceforge.net/projects/jxls/ ...

  7. java jxl_java 中JXL操作Excel实例详解

    JXL操作Excel 前言: jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一 ...

  8. java jxl mergecells_java 中JXL操作Excel实例详解

    JXL操作Excel 前言: jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一 ...

  9. java 操作excel jxl_java 中JXL操作Excel实例详解

    JXL操作Excel 前言: jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一 ...

  10. Excel中VBA操作工作表相关

    VBA中已有工作簿合并表格数据 Sub 合并目录所有工作簿全部工作表() On Error Resume Next Dim MP, MN, AW, Wbn, wn Dim Wb As Workbook ...

最新文章

  1. java 算法笔试题_【干货】经典算法面试题代码实现-Java版
  2. Serverless 场景下 Pod 创建效率优化
  3. 聊聊如何构建自驱团队(3)
  4. EntityFramework Code-First—领域类配置之DataAnnotations
  5. cnetos7 mysql5.6 utf8设置_CentOS7下安装MySQL 5.6修改字符集为utf8并开放端口允许远程访问...
  6. 阿里最“短命”P10员工?曝前百度云高管加盟钉钉不足三周被开除
  7. BPMN2.0--消息事件(message)
  8. 中国夹层玻璃板行业市场供需与战略研究报告
  9. 过程 sp_addlinkedsrvlogin,第 91 行解密过程中出错的解决办法
  10. 王校长撩妹不成反被锤爆?再有钱的舔狗也只是舔狗【Python爬虫实战:微博评论采取】
  11. 使用Flutter开发一个仿微信飞机大战游戏
  12. 坚持努力,在黑暗中寻找光明——我的2014
  13. 如何将照片裁剪为圆形?教你一招图片裁剪的技巧
  14. 老电脑可以安装win11系统吗
  15. 蓝桥杯嵌入式总结(KEY配置_按键扫描(三行代码)_矩阵按键_GPIO口输入和输出类型)
  16. Mysql compact行格式
  17. 如何使用TeamViewer在局域网内远程连接另一台电脑
  18. 渗透测试之资产测绘篇
  19. LeetCode题解(0919):设计完全二叉树插入器(Python)
  20. Android 修改屏幕亮度方案

热门文章

  1. [转]介绍“Razor”— ASP.NET的一个新视图引擎
  2. Difference between natural join and inner join
  3. Oracle误删除后的找回方法
  4. Windows活动目录(域服务器)经典系列图文教程
  5. ES aggr terms nested study
  6. 让程序员崩溃的一句话。。。
  7. 牛逼!Intellij IDEA竟然有个功能可自动生成代码,你用过没?
  8. 你还在为Springboot服务吞吐量而烦扰吗?如何提升本文告诉你
  9. 分布式系统如何设计,看看Elasticsearch是怎么做的
  10. 工地小哥逆袭转行程序员的真实故事