Microsoft KB Archive/313510

= BUG: Error message when you call an OleDbDataReader object: System.InvalidCastException: QueryInterface for interface IRowset failed =

Article ID: 313510

Article Last Modified on 3/10/2006

-

APPLIES TO


 * Microsoft .NET Framework 1.1 Service Pack 1
 * Microsoft Visual Studio .NET 2002 Professional Edition, when used with:
 * Microsoft Visual C# .NET 2002 Standard Edition

-



This article was previously published under Q313510



SYMPTOMS
When you call an OleDbDataReader object that invokes the Read method from a different single-threaded apartment (STA) thread than the object was created in, you receive the following exception:

System.InvalidOperationException: The OleDbDataReader.Read must be used from the same thread on which is was created if that thread's ApartmentState was not ApartmentState.MTA



CAUSE
This behavior occurs because the component that implements IRowset does not aggregate the free-threaded marshaller, even though it is marked with a threading model of both. This causes OLE32 to use its own IMarshal, which requires either a typelib or a proxy and stub to be registered for the interface.



RESOLUTION
To work around this issue, make sure that you use an OleDB object only from the STA thread that it is created in, or from any multithreaded apartment (MTA) if it was created on an MTA.



STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.



Steps to Reproduce the Problem
  Use Notepad or another text editor to create a C# file named STA_bug.cs with the following code: using System; using System.Data; using System.Data.OleDb; using System.Diagnostics; using System.Threading;

public class Class1 {

static public ManualResetEvent s_resetevent; static public OleDbDataReader s_datareader;

static public void Main(string[] args) { Thread.CurrentThread.ApartmentState = ApartmentState.STA; // MTA works try { BugMultiThread; }       catch(Exception e) { Console.WriteLine(e.ToString); }   } static public void BugMultiThread { // We use NT authentication here. OleDbConnection connection = new OleDbConnection(&quot;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=pubs;Data Source=(local)&quot;);

// If you want to use SQL Mode authentication, // make necessary changes to point to your SQL Server. // OleDbConnection connection = new OleDbConnection(&quot;Provider=SQLOLEDB;Data Source=myserver;Initial Catalog=pubs;User ID=username;Password=password;&quot;);

connection.Open; try { OleDbCommand command = new OleDbCommand(&quot;select top 2 * from authors; select top 2 * from publishers;&quot;, connection); s_datareader = command.ExecuteReader;

s_resetevent = new ManualResetEvent(false); (new Thread(new ThreadStart(BugMultiThreadRead))).Start; s_resetevent.WaitOne; }       finally { if ((null != s_datareader) && !s_datareader.IsClosed) { s_datareader.Close; }           connection.Close; }   }

static public void BugMultiThreadRead { try { Console.WriteLine(&quot;BugMultiThreadRead: start&quot;); if (null != s_datareader) { try { do { while (s_datareader.Read) { Console.Write(&quot;.&quot;); }                       Console.Write(&quot;*&quot;); } while (s_datareader.NextResult); }               catch(Exception e) { Console.WriteLine; Console.WriteLine(e.ToString); }               Console.WriteLine; }       }        finally { Console.WriteLine(&quot;BugMultiThreadRead: signal finish&quot;); s_resetevent.Set; }   } }                      Use the Visual Studio .NET command prompt to execute the following command: csc.exe /r:system.dll /r:system.data.dll STA_bug.cs & STA_bug.exe Note that you receive the following exceptions: BugMultiThreadRead: start

System.InvalidOperationException: The OleDbDataReader.Read must be used from the same thread on which is was created if that thread's ApartmentState was not ApartmentState.MTA ---> System.InvalidCastException: QueryInterface for interface IRowset failed. at System.Data.Common.IRowset.GetNextRows(IntPtr hChapter, Int32 lRowsOffset, Int32 cRows, Int32& pcRowsObtained, IntPtr& pprghRows) at System.Data.OleDb.OleDbDataReader.GetRowHandles --- End of inner exception stack trace --- at System.Data.OleDb.OleDbDataReader.GetRowHandles at System.Data.OleDb.OleDbDataReader.ReadRowset at System.Data.OleDb.OleDbDataReader.Read at Class1.BugMultiThreadRead

BugMultiThreadRead: signal finish   If you make a revision to use MTA, as follows Thread.CurrentThread.ApartmentState = ApartmentState.MTA; you receive the correct result: BugMultiThreadRead: start ..*..* BugMultiThreadRead: signal finish 

Keywords: kberrmsg kbbug kbvs2002sp1sweep KB313510

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.