Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Hi Guys,

 

I wrote a piece of code here to open and close an excel file..

Everything works fine..But im not sure why when i go to the task manager, the instance of excel is still there running > means that the excel file is not closed properly..Do you guys have any idea what is the problem?

 

Thankx in advance

 

oXL = new Excel.Application();
	
oWB = oXL.Workbooks.Open("C:\\Content.xls",
Type.Missing,false,
Type.Missing,Type.Missing,
Type.Missing,Type.Missing,
Type.Missing,Type.Missing,true,
Type.Missing,Type.Missing,Type.Missing);
			
oWB.Close(false,Type.Missing,Type.Missing);

oXL.Workbooks.Close();

oXL.Quit();

Posted

I had the exact same problem. There is something about Excel that makes it hard to clean up. We know that every Excel object, worksheets, workbooks, the application itself, all will leave that EXCEL.EXE in memory if not cleaned up. However, there must be something else as well.

 

I took two approaches to solving this problem. I was under extreme time constraints, so all of these steps may not be necessary, but it did solve the problem and the problem remains solved to this day.

 

First, I implemented the following Destructor and Dispose method in my ClassXL class.

 

~ClassXL()
{
 if (xlapp != null)
 Dispose(false);
}

public void Dispose()
{
 Dispose(true);
 GC.SuppressFinalize(this);
}

public virtual void Dispose(bool disposing)
{
 if (!this.disposed)
 {
   for (int i = 0; i < alXlObjects.Count; i++)
   {
     int referenceCount = 0;
     do
     {
       referenceCount = System.Runtime.InteropServices.Marshal.ReleaseComObject(alXlObjects[i]);
       alXlObjects[i] = null;
     }
     while (referenceCount > 0);
   }

   this.xlapp = null;
   if (disposing)
   {
     GC.SuppressFinalize(this);
   }
 }
 disposed = true;
}

As you can see, the Dispose method iterates through an ArrayList containing all the XL objects that I created during initialization. For example:

 

if (this.xlapp == null)
{
 this.xlapp = new excel9.Application();
 alXlObjects.Add(this.xlapp);
}

 

Finally, I also included a call to GC.Collect from the consumer class using the ClassXL.

 

classXL.Dispose();
GC.Collect();

 

Like I said, not all these steps may be necessary, but it fixed the problem you described back in November 2004 and the problem remains fixed to this day.

"Never ascribe to malice that which can adequately be explained by incompetence." -- Napolean Bonaparte
Posted

I use the following:

 

Private Sub DisposeObject(ByVal obj As Object)
       Dim count As Integer
       Try
           If obj Is Nothing Then Exit Try
           count = Marshal.ReleaseComObject(obj)
           While count > 0
               count = Marshal.ReleaseComObject(obj)
           End While
       Catch ex As Exception
       Finally
           obj = Nothing
       End Try
   End Sub

 

Which I found somewhere when first reading up on Excel automation through .Net. You basically need to call it on all objects when you're done with them.

 

:)

Please check the Knowledge Base before you post.

"Computers are useless. They can only give you answers." - Pablo Picasso

The Code Net

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...