sql server programming:
Hi,
I have a CLR table-valued function that pulls data from a 3rdParty OLEDB
provider.
When I call Dispose() on the .NET objects (System.Data.OleDb.*) and the end
of my function Init() method, it causes COM interop errors which I cannot
catch. I think it's a ThreadAbortException that causes the code to abort and
stop executing immediately. Full stack trace and sample code below.
This same code works fine in regular .NET CLR. If I don't call Dispose() in
the function Init() method, then the same error is generated anyways and my
FillRow() method still never gets called. If I don't use OLE DB and
hard-code the data instead, everything works OK.
Any suggestions?
Thanks,
Chris Nusca
cnusca@infusiondev_nospam.com
***Stack Trace***
Invalid user code has been identified by .Net Framework Managed Debug
Assistant 'reportAvOnComRelease':
An exception was caught but handled while releasing a COM interface pointer
through Marshal.Release or Marshal.ReleaseComObject or implicitly after the
corresponding RuntimeCallableWrapper was garbage collected. This is the
result of a user refcount error or other problem with a COM object's
Release. Make sure refcounts are managed properly. The COM interface
pointer's original vtable pointer was 0x69b79280. While these types of
exceptions are caught by the CLR, they can still lead to corruption and data
loss so if possible the issue causing the exception should be addressed
at System.Runtime.InteropServices.Marshal.InternalReleaseComObject(Object
o)
at System.__ComObject.ReleaseSelf()
at System.Runtime.InteropServices.Marshal.ReleaseComObject(Object o)
at System.Data.OleDb.OleDbDataReader.DisposeNativeRowset()
at System.Data.OleDb.OleDbDataReader.Close()
at System.Data.OleDb.OleDbDataReader.CloseReaderFromConnection(Boolean
canceling)
at System.Data.OleDb.OleDbReferenceCollection.NotifyItem(Int32 message,
Int32 tag, Object value)
at System.Data.ProviderBase.DbReferenceCollection.Notify(Int32 message)
at System.Data.OleDb.OleDbConnectionInternal.Deactivate()
at
System.Data.ProviderBase.DbConnectionInternal.CloseConnection(DbConnection
owningObject, DbConnectionFactory connectionFactory)
at System.Data.OleDb.OleDbConnection.Close()
at ReportManager.ExecuteHelper2(String commandString)
at ReportManager.ExecuteReport2(IInvestranReport report, List`1
inputParms)
at ReportManager.fnGetCompanies() CHRIS: THIS IS MY CODE
at SQLCLR_Eval(IntPtr , IntPtr )
at System.Data.SqlServer.Internal.SqlAppDomain.EvalDelegate.Invoke(IntPtr
Arg1, IntPtr Arg2)
***Sample C# code***
private static List<DbDataRecord> ExecuteHelper2(string commandString)
{
OleDbConnection conn = null;
OleDbCommand cmd = null;
OleDbDataReader rdr = null;
try
{
...
}
catch (Exception ex)
{
...
}
finally
{
try
{
if (cmd != null)
{
cmd.Dispose();
}
}
catch { }
try
{
if (conn != null)
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
conn.Dispose();
}
}
catch { }
try
{
if (rdr != null)
{
if (!rdr.IsClosed)
{
rdr.Close();
}
rdr.Dispose();
}
}
catch { }
}
}