2012-05-30 7 views
7

.Net4 C# VSTO4 Excel Add-In:

Die folgende Funktion sehr oft genannt wird, lassen Sie uns jede Sekunde sagen:Worksheet.Name verursacht OutOfMemoryException

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

Nach einer Weile Ich erhalte die folgende Ausnahme:

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)-------------------------------------------------------------------------------------------------------- 

Telefonvorwahl ist:

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

Ich habe keine Ahnung, warum ich eine Ausnahme bin immer!

Kann es vielleicht helfen, eine "Verwendung" in GetWorksheetUniqueIdentifier zu nehmen?

using(worksheet) 
{ 
    return string.Format("[{0}]{1}", workbook.Name, worksheet.Name); 
} 

Hat jemand eine Antwort?

+1

sieht aus, als ob etwas beim Einfügen in ein Wörterbuch schief läuft, können Sie den kompletten StackTrace teilen –

+2

Woher kommt dieser Code oder wie wird er benutzt? Es scheint nicht die direkte Ursache des Problems zu sein (das innerhalb einer Dictionary-Größenänderungsmethode liegt), so dass der aufrufende Code das Problem haben kann. –

+0

Werfen Sie nicht das 'Arbeitsblatt'-Objekt auf, was passieren würde, wenn Sie die von Ihnen gepostete' using'-Anweisung verwenden würden. Es ist wahrscheinlich, dass der Aufrufer nach Beendigung der Methode noch auf "Arbeitsblatt" verweisen muss. – Keith

Antwort

0

Versuche explizit die COM-Objekte loslassen:

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

Dies wurde bekannt, dass Speicherprobleme in einigen Office-bezogenen Szenarien zu beheben.

+0

** Ich weiß nicht, ob das das Problem wirklich behebt, weil ich es nicht reproduzieren kann. Aber es ist die beste Antwort bisher. ** – jreichert

Verwandte Themen