They call tons of COM objects in .net code. We suspect of .net clr doesn't release COM object correctly.
I found a good article about ReleaseComObject from Chris Brumme, and I have some code to do this job: Realease
COM object in .net manage code.
First I have a COMWrapper, client will call this wrapper not calling com object directly, and I will implement
IDipose interface in this wrapper class, in which I will release all resouces.
following are related codes:
using System;
namespace COMDipose
{
public class ComPlusWrapper : IDisposable
{
private object _ComPlusObject;
private Type _type;
protected bool _IsDisposed = false;
public ComPlusWrapper(string ProgId)
{
_type = Type.GetTypeFromProgID(ProgId, true);
_ComPlusObject = System.Activator.CreateInstance(_type);
}
~ComPlusWrapper()
{
this.Dispose();
}
public object ComPlusObject
{
get
{
if(this._IsDisposed)
{
throw new ObjectDisposedException(null);
}
return _ComPlusObject;
}
}
public Type ComPlusType
{
get
{
if(this._IsDisposed)
{
throw new ObjectDisposedException(null);
}
return _type;
}
}
public void Dispose()
{
if(!this._IsDisposed)
{
IDisposable dispose = _ComPlusObject as IDisposable;
if(dispose != null)
{
dispose.Dispose();
}
else
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(_ComPlusObject);
}
_type = null;
_ComPlusObject = null;
}
GC.SuppressFinalize(this); this._IsDisposed = true;
}
}
}
client code:
COMDipose.ComPlusWrapper a = new ComPlusWrapper("ADOdb.connection");
ADODB.Connection b= (a.ComPlusObject) as ADODB.Connection ;
b.Open("workstation id=GZSTEVE;packet size=4096;data source=gzsteve;initial catalog=pubs","sa","******",0);
b.Close();
b=null;
a.Dispose();
And I modified my client side snippets:
using(COMDipose.ComPlusWrapper myVariable = new ComPlusWrapper("ADOdb.connection"))
{
ADODB.Connection b= (a.ComPlusObject) as ADODB.Connection ;
b.Open("workstation id=GZSTEVE;packet size=4096;data source=gzsteve;initial catalog=pubs","sa","******",0);
b.Close();
}
C# ensures IDisposable::Dispose is called here exception or no exception