Worksheet.Name导致OutOfMemoryException

.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); } 

过了一段时间,我收到以下exception:

 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, IEnumerable`1 parameters, DynamicMetaObject[] args, 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[] args, 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}", workbook.Name, 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相关scheme中的内存问题。