在Silverlight中使用COM组件 *** 作Excel,大概需求是在Silverlight应用程序中初始化Excel表格的相关基本信息,然后打开Excel。用户在Excel中输入相关数据,最后在用户点击保存时,把特定一列的数据返回到Silverlight应用程序界面。
dynamic _excel = automationFactory.CreateObject("Excel.Application");
问题在于,Excel的关闭是用户自行决定的,不能在用户保存成功后强制关闭......所以在下面的事件中不能做强制销进程。
_excel.WorkbookAfterSave += new AppEvents_WorkbookAfterSaveEventHandler(ExcelApp_WorkbookAfterSave);
还好,有另外一个事件:
_excel.WorkbookBeforeClose += new AppEvents_WorkbookBeforeCloseEventHandler(ExcelApp_WorkbookBeforeClose);
因为这是在关闭前的,用户也有可能在点击关闭按钮时没有保存,d出确认框的时候,点了取消……所以不能 _excel.Workbooks.Close()
注:((Idisposable)_excel).dispose() 这句最重要了,如果没这个,EXcel.EXE 进程会一直在
/// <summary> /// 关闭前 </summary> private voID ExcelApp_WorkbookBeforeClose(dynamic Wb,ref bool Cancel) { if (_excel != null) { // _excel.Workbooks.Close();不能用这句,否则_excel已经为null了 _excel.Quit(); ((Idisposable)_excel).dispose(); _excel = ; GC.Collect(); } }
OK~这样,不管是点击保存然后关闭,还是不保存就关闭,当Excel关闭时,相应的Excel.EXE进程就会自动销毁 :(
补充一些:
AppEvents_WorkbookBeforeCloseEventHandler、AppEvents_WorkbookAfterSaveEventHandler是参照MSDN写的委托变量
delegate voID AppEvents_WorkbookBeforeCloseEventHandler([In] dynamic Wb,[In,Out] Cancel); delegate voID AppEvents_WorkbookBeforeSaveEventHandler(dynamic Wb,bool SaveAsUI,ref bool Cancel); voID AppEvents_WorkbookAfterSaveEventHandler(dynamic Wb,255)">bool Success);
在前几天写到的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 12 Com对象集合13 14 private List<ComObjectWrapper> _children = new List<ComObjectWrapper>();15 16 17 Com对象是否被释放的的标记18 true情况下释放出来19 20 public Boolean disposed21 {22 get23 {24 return _disposed;25 }26 }27 28 29 增加对象到集合,并为对象绑定释放事件30 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 39 子对象被释放时在集合移除40 41 <param name="sender"></param>42 <param name="e"></param>43 voID child_ComObjectdisposed(object sender,EventArgs e)44 45 _children.Remove(sender as ComObjectWrapper);46 47 48 49 释放Com对象(集合所有对象)50 51 ReleaseChildren()52 53 foreach (ComObjectWrapper child in _children)54 55 child.ComObjectdisposed -= 56 child.dispose();57 58 59 _children.Clear();60 61 62 63 执行释放资源(虚函数)64 65 virtual Dodispose() { }66 67 #region Idisposable Members68 69 70 释放Excel程序资源71 72 dispose()73 74 try75 76 释放对象77 ReleaseChildren();78 79 Dodispose();80 81 _disposed = true82 83 if (ComObjectdisposed != )84 {85 ComObjectdisposed(this,EventArgs.Empty);86 }87 88 catch { }89 90 91 #endregion92 }
2、InstanceManager类,对所有Excel的Com对象进行管理
@H_404_429@ InstanceManager Excel对象实例集合static List<ComObjectWrapper> _excelApplications = 8 9 新增一个Excel对象10 <returns></returns>12 static ExcelApplication CreateAppication()13 14 自动化功能是否可用15 if (!automationFactory.IsAvailable) return 16 17 dynamic excelObject = automationFactory.CreateObject("Excel.Application");18 19 ExcelApplication application = ExcelApplication(excelObject);20 _excelApplications.Add(application);21 application.ComObjectdisposed += System.EventHandler(application_ComObjectdisposed); application;24 25 26 27 30 static voID application_ComObjectdisposed(31 32 34 _excelApplications.Remove(sender 35 36 37 38 取得已经运行的Excel进程实例。<param name="create"></param>43 44 static ExcelApplication GetApplication( create)45 46 47 48 49 dynamic excelObject = 50 51 在已经生成的com对象集合中取得没有被释放的实例52 foreach (ExcelApplication excel _excelApplications)53 54 if (!excel.disposed)55 56 excel;58 59 60 61 62 excelObject = automationFactory.Getobject(63 64 catch65 66 if (create)67 68 excelObject = automationFactory.CreateObject(69 70 71 72 if (excelObject != 74 ExcelApplication application = _excelApplications.Add(application);76 application.ComObjectdisposed += 77 78 79 else80 81 82 83 84 85 86 释放所有Excel进程87 88 ReleaseAll()90 foreach (ComObjectWrapper wrapper 91 92 wrapper.ComObjectdisposed -= EventHandler(application_ComObjectdisposed);93 wrapper.dispose();94 95 _excelApplications.Clear();96 97 }使用时,在ExcelApplication的封装类进行调用Exit()函数即可。
注意,封装类要进行继续1中的ComObjectWrapper类, 并重写Dodispose。封装类的代码就不上了,百度或者谷歌都有:(
@H_404_429@ ExcelApplication : ComObjectWrapper{ <summary>Excel程序退出 </summary> Exit() { _excel.Quit(); dispose(); } Com对象的释放处理 overrIDe Dodispose() { try { Workbooks.Close(); Workbooks.dispose(); _excel.Quit(); ((Idisposable)_excel).dispose(); _excel = ; } { } } other code ...........}
ExcelWorkbook : ComObjectWrapper
{
Dodispose() { { ((Idisposable)workBook).dispose(); } { } }.................other code } 总结
以上是内存溢出为你收集整理的Silverlight *** 作Excel 中的进程资源释放问题全部内容,希望文章能够帮你解决Silverlight *** 作Excel 中的进程资源释放问题所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)