avoid memory leaks

Sep 26, 2011 at 9:01 PM
Edited Sep 26, 2011 at 10:08 PM

I notice com proxy count increases dramatically as my AddIn runs so I try to clean up and dispose unused objects.  Now I track down the following method,

after it runs, proxy count increases by 2  (nextRange.Value2 = relSb.Tostring())

I wonder how to make it memory-leak free.  It seems set Value2 will create com proxy and I am unable to release it. thanks

        private void SetFormulaToCell_AjustButtonsEnabled(Range selectedRange, StringBuilder relSb)
        {
            if (selectedRange.Count != 0)
            {
                var cells = selectedRange.Cells;
                var nextRange = cells[1, 1];
                nextRange.Value2 = relSb.ToString();
                 nextRange.Dispose();
                cells.Dispose();
            }
            selectedRange.Dispose();
        }

Coordinator
Sep 26, 2011 at 10:07 PM
Edited Sep 26, 2011 at 10:12 PM

hmm i'm not sure i'm understand your question (it's 00:06am here...)
you mean nextRange.Value2 = "anyway"; increases the comproxy count by 2?
this is impossible. are you sure? i do a test tomorrow. when the counter is changed netoffice holds
the proxy in a internal table.  you not have to fear a memory leak is occured.

btw: its not necessary to dispose nextRange and cells. the objects was created about selectedRange.
with selectedRange.Dispose(); in your last line you dispose also the created childs and childs of childs and so on.
use DisposeChildInstances() to dipose all descendents and keep the parent object(means selectedRange) still alive. 
when nextRange is disposed all childs was diposed to, okay maybe value2 creates a proxy but anyway, he is also diposed with parent disposing.

 

 

Sep 27, 2011 at 2:32 PM

Yes,  nextRange.Value2 = "anyway"; increases the comproxy count by 2. that's what I see.  thanks

Coordinator
Sep 27, 2011 at 2:47 PM
Edited Sep 27, 2011 at 2:47 PM

sorry yinru but its impossible what you say. look!

   int proxyCount = LateBindingApi.Core.Factory.ProxyCount;
   var cells = selectedRange.Cells;
   proxyCount = LateBindingApi.Core.Factory.ProxyCount;
  // one proxy more

  var nextRange = cells[1, 1];
  proxyCount = LateBindingApi.Core.Factory.ProxyCount; 
  // two proxies more

  nextRange.Value2 = "anyway";
  proxyCount = LateBindingApi.Core.Factory.ProxyCount; 
  // no proxy count changing

Sep 27, 2011 at 5:49 PM
Edited Sep 27, 2011 at 6:06 PM
Hi, thanks.
I tried to get a video for you but could not get camstudio work
I did see nextRange.Value2 = relSb.ToString(); proxycount increases by 2.

I have an xls file with VBA code and with my addin installed, the VBA has nothing to do with my AddIn,
It does a lot of delete row, combine one row of data to the next row, etc.
eg.
I debug the code and found every time when a cell value is assigned , com proxy count increases by 2

For i = 1 To 80
Sheets("Organized").Cells(Output_Counter, 3 + i) = Point_Date_Value(i)
Next i

the VBA code heavily access each cell in loop, which make com proxy count increases dramatically

I can email you the VBA code if this is your personal mailbox. (I do not want to post VBA code to discussion there b/c it is not my code)

thanks

Sep 27, 2011 at 7:22 PM
Edited Sep 27, 2011 at 8:11 PM

Here is what I debug in VS2010 and it shows com proxy changes
I am using 1.2 release.
Hmm, if it works on your side, I suspect I did something wrong or miss something?
I emailed swf file to your mailbox, too.

thanks

Sep 27, 2011 at 10:26 PM

Thanks a lot for your help & patience, SebastianDotNet, appreciate it!

The issue is solved!

Long time ago a developer hooked up an empty SheetChangeEvent which causes com proxy count increases by 2 every time VBA code does Sheets(*), at that time it was COM AddIn using PIA.  I did not change this after I switch to NetOffice

Now I add two dispose methods in the handler and the issue is solved.         

void Application_SheetChange(COMObject Sh, Excel.Range Target)
        {
           // TODO: In future when the sheet selection changes - unhook event on current sheet and add event on new sheet.
           Sh.Dispose();
           if(Target!=null) Target.Dispose();
        }

thanks again