c# – Worksheet.Name导致OutOfMemoryException

前端之家收集整理的这篇文章主要介绍了c# – 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);
    }

过了一会儿,我得到以下异常:

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相关的场景中的内存问题.

猜你在找的C#相关文章