.Net4 C#VSTO4 Excel加载项:
/// <summary> /// Gets a unique identifier string of for the worksheet in the format [WorkbookName]WorksheetName /// </summary> /// <param name="workbook">The workbook.</param> /// <param name="worksheet">The worksheet.</param> /// <returns> /// A unique worksheet identifier string,or an empty string. /// </returns> public static string GetWorksheetUniqueIdentifier(Workbook workbook,dynamic worksheet) { if (workbook == null) return string.Empty; if (worksheet == null) return string.Empty;//Note: Worksheet can also be a diagram! return string.Format("[{0}]{1}",workbook.Name,worksheet.Name); }
过了一会儿,我得到以下异常:
System.OutOfMemoryException at System.Collections.Generic.Dictionary`2.Resize() at System.Collections.Generic.Dictionary`2.Insert(TKey key,TValue value,Boolean add) at Microsoft.CSharp.RuntimeBinder.Semantics.SYMTBL.InsertChildNoGrow(Symbol child) at Microsoft.CSharp.RuntimeBinder.Semantics.SymFactoryBase.newBasicSym(SYMKIND kind,Name name,ParentSymbol parent) at Microsoft.CSharp.RuntimeBinder.Semantics.SymFactory.CreateLocalVar(Name name,ParentSymbol parent,CType type) at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.PopulateLocalScope(DynamicMetaObjectBinder payload,Scope pScope,ArgumentObject[] arguments,IEnumerable`1 parameterExpressions,Dictionary`2 dictionary) at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindCore(DynamicMetaObjectBinder payload,IEnumerable`1 parameters,DynamicMetaObject[] args,DynamicMetaObject& deferredBinding) at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(DynamicMetaObjectBinder payload,DynamicMetaObject& deferredBinding) at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action,RuntimeBinder binder,IEnumerable`1 args,IEnumerable`1 arginfos,DynamicMetaObject onBindingError) at Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder.FallbackInvokeMember(DynamicMetaObject target,DynamicMetaObject errorSuggestion) at System.Dynamic.DynamicMetaObject.BindInvokeMember(InvokeMemberBinder binder,DynamicMetaObject[] args) at System.Dynamic.InvokeMemberBinder.Bind(DynamicMetaObject target,DynamicMetaObject[] args) at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args,ReadOnlyCollection`1 parameters,LabelTarget returnLabel) at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site,Object[] args) at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site,T0 arg0,T1 arg1,T2 arg2) at CallSite.Target(Closure,CallSite,Object,Object ) at TestAddIn.ExcelAccessor.GetWorksheetUniqueIdentifier(Workbook workbook,Object worksheet) at TestAddIn.ExcelAccessor.GetCurrentWorksheetUniqueIdentifier() at TestAddIn.ExcelAccessor.timerExcelObserver_Tick(Object sender,EventArgs e)--------------------------------------------------------------------------------------------------------
private static Timer timerExcelObserver = new Timer(); ... timerExcelObserver.Tick += new EventHandler(this.timerExcelObserver_Tick); timerExcelObserver.Interval = 1000; timerExcelObserver.Start(); ... private void timerExcelObserver_Tick(object sender,EventArgs e) { ... var updatedWorksheetIdentifierString = GetCurrentWorksheetUniqueIdentifier(); ... } public static string GetCurrentWorksheetUniqueIdentifier() { return GetWorksheetUniqueIdentifier(ExcelApplication.ActiveWorkbook,ExcelApplication.ActiveSheet); }
我不知道为什么我会得到例外!
在GetWorksheetUniqueIdentifier中使用“使用”可能有帮助吗?
using(worksheet) { return string.Format("[{0}]{1}",worksheet.Name); }
有人有答案吗?
解决方法
尝试显式释放COM对象:
public static string GetCurrentWorksheetUniqueIdentifier() { var workbook = ExcelApplication.ActiveWorkbook; var worksheet = ExcelApplication.ActiveSheet; try { return GetWorksheetUniqueIdentifier(workbook,worksheet); } finally { if (workbook != null && Marshal.IsComObject(workbook)) Marshal.ReleaseComObject(workbook); if (worksheet != null && Marshal.IsComObject(worksheet)) Marshal.ReleaseComObject(worksheet); } }
众所周知,这可以修复某些与Office相关的场景中的内存问题.