2012-05-30 20 views
7

.Net4 C# VSTO4 Excel Add-In:

Chức năng sau đây được gọi là rất thường xuyên, chúng ta hãy nói mỗi giây:Worksheet.Name gây 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); 
    } 

Sau một thời gian, tôi nhận được ngoại lệ sau đây:

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

mã số điện thoại là:

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

Tôi không biết tại sao tôi bị ngoại lệ!

Có thể giúp bạn "sử dụng" trong GetWorksheetUniqueIdentifier không?

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

Có ai có câu trả lời không?

+1

có vẻ như đã xảy ra sự cố khi chèn vào một số từ điển, bạn có thể chia sẻ ngăn xếp hoàn chỉnh –

+2

Mã này được gọi từ đâu hoặc nó được sử dụng như thế nào? Nó không xuất hiện để được nguyên nhân trực tiếp của vấn đề (mà là chết bên trong một phương pháp thay đổi kích thước từ điển), do đó, mã gọi có thể có vấn đề. –

+0

Không vứt bỏ đối tượng 'bảng tính', đó là điều sẽ xảy ra nếu bạn sử dụng câu lệnh' using' mà bạn đã đăng. Có khả năng người gọi vẫn cần tham khảo 'bảng tính 'sau khi phương thức của bạn kết thúc. – Keith

Trả lời

0

Cố gắng giải phóng các đối tượng COM một cách rõ ràng:

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

này đã được biết đến để sửa chữa các vấn đề bộ nhớ trong một số kịch bản văn phòng liên quan đến.

+0

** Tôi không biết điều này có thực sự khắc phục được sự cố không, vì tôi không thể tái tạo nó. Nhưng đó là câu trả lời tốt nhất cho đến nay. ** – jreichert

Các vấn đề liên quan