Silverlight 操作Excel 中的进程资源释放问题(续)
在前几天写到的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 中的进程资源释放问题(续)相关推荐
- python 操作 excel 百度网盘 资源下载_批量读取excel百度链接转存到自己的百度网盘...
[Python] 纯文本查看 复制代码#!/usr/local/Cellar/python/3.7.1/bin # -*- coding: UTF-8 -*- import requests,re,t ...
- 关于使用QAxObject类操作Excel中出现QAxBase : Error calling IDispatch member SaveAs:Exception thrown by server解决
前段时间在使用QAxObject对数据库文件导出为Excel中遇到了QAxBase : Error calling IDispatch member SaveAs:Exception thrown b ...
- qt中关闭窗口资源释放问题
针对QDialog对象,如果是栈上分配的,就不存在资源泄漏问题,但是当对象是new出来的,并且以局部对像存在,当关闭时,窗口只是隐藏,资源是没有释放的,每次exec后者需要delete来释放,另外一种 ...
- notebook中kiil进程从而释放显存的方法
import ospid = os.getpid() !kill -9 $pid
- Java操作Excel中HSSFCell.CELL_TYPE_STRING、BOOLEAN、NUMERIC无定义解决方法
错误原因:jar包版本更新,官方改动: 解决方法: 导入CellType包import org.apache.poi.ss.usermodel.CellType 使用CellType.STRING代替 ...
- JXL(JXLS)的使用:java中操作Excel的解决方案之一。
摘要: 本文讲述的是如何使用开源项目JXSL来对Excel及其内部的数据进行操作,本人整理汇总自网络. JXLS项目主页: http://sourceforge.net/projects/jxls/ ...
- java jxl_java 中JXL操作Excel实例详解
JXL操作Excel 前言: jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一 ...
- java jxl mergecells_java 中JXL操作Excel实例详解
JXL操作Excel 前言: jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一 ...
- java 操作excel jxl_java 中JXL操作Excel实例详解
JXL操作Excel 前言: jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一 ...
- Excel中VBA操作工作表相关
VBA中已有工作簿合并表格数据 Sub 合并目录所有工作簿全部工作表() On Error Resume Next Dim MP, MN, AW, Wbn, wn Dim Wb As Workbook ...
最新文章
- java 算法笔试题_【干货】经典算法面试题代码实现-Java版
- Serverless 场景下 Pod 创建效率优化
- 聊聊如何构建自驱团队(3)
- EntityFramework Code-First—领域类配置之DataAnnotations
- cnetos7 mysql5.6 utf8设置_CentOS7下安装MySQL 5.6修改字符集为utf8并开放端口允许远程访问...
- 阿里最“短命”P10员工?曝前百度云高管加盟钉钉不足三周被开除
- BPMN2.0--消息事件(message)
- 中国夹层玻璃板行业市场供需与战略研究报告
- 过程 sp_addlinkedsrvlogin,第 91 行解密过程中出错的解决办法
- 王校长撩妹不成反被锤爆?再有钱的舔狗也只是舔狗【Python爬虫实战:微博评论采取】
- 使用Flutter开发一个仿微信飞机大战游戏
- 坚持努力,在黑暗中寻找光明——我的2014
- 如何将照片裁剪为圆形?教你一招图片裁剪的技巧
- 老电脑可以安装win11系统吗
- 蓝桥杯嵌入式总结(KEY配置_按键扫描(三行代码)_矩阵按键_GPIO口输入和输出类型)
- Mysql compact行格式
- 如何使用TeamViewer在局域网内远程连接另一台电脑
- 渗透测试之资产测绘篇
- LeetCode题解(0919):设计完全二叉树插入器(Python)
- Android 修改屏幕亮度方案
热门文章
- [转]介绍“Razor”— ASP.NET的一个新视图引擎
- Difference between natural join and inner join
- Oracle误删除后的找回方法
- Windows活动目录(域服务器)经典系列图文教程
- ES aggr terms nested study
- 让程序员崩溃的一句话。。。
- 牛逼!Intellij IDEA竟然有个功能可自动生成代码,你用过没?
- 你还在为Springboot服务吞吐量而烦扰吗?如何提升本文告诉你
- 分布式系统如何设计,看看Elasticsearch是怎么做的
- 工地小哥逆袭转行程序员的真实故事