I have been playing with the demo code from this msdn article by Jeffrey Richter.
I have added a new function to his ApmToCcrAdapters to handle the SqlCommand.BeginExecuteReader. Only it is closing the reader before I can read it.
The following code is used to provide a FromIteratorHandler:
private static IEnumerator<ITask> AsyncReaderDemoHandler() { SqlDataReader reader = null; SqlConnection connection = new SqlConnection(@'Data Source=.\SQLEXPRESS;Initial Catalog=BizData;Integrated Security=True;Async=True;'); string query = 'SELECT * FROM Account;'; SqlCommand command = new SqlCommand(query,connection); connection.Open(); yield return Arbiter.Choice(ApmToCcrAdapters.GetReader(command), delegate(SqlDataReader r) { Msg('Got SQL data'); reader = r; }, delegate(Exception e) { Msg('Failed to get SQL data'); }); connection.Close(); if (reader == null) yield break; //This is where the code fails: Reader is Closed! while (reader.Read()) { Console.WriteLine(reader['Account']); } }
Which in turn calls the following code:
/// <summary> /// Gets the Reader, requires connection to be managed /// </summary> public static PortSet<SqlDataReader, Exception> GetReader(SqlCommand sqlCommand) { Port<SqlDataReader> portResponse = null; Port<Exception> portException = null; GetReaderResponse(sqlCommand, ref portResponse, ref portException); return new PortSet<SqlDataReader, Exception>(portResponse, portException); } // Wrapper for SqlCommand's GetResponse public static void GetReaderResponse(SqlCommand sqlCom, ref Port<SqlDataReader> portResponse, ref Port<Exception> portException) { EnsurePortsExist(ref portResponse, ref portException); sqlCom.BeginExecuteReader(ApmResultToCcrResultFactory.Create( portResponse, portException, delegate(IAsyncResult ar) { return sqlCom.EndExecuteReader(ar); }), null); }
The connection must remain open for the Reader to work. I believe closing the connection is your problem. Leave the connection open and call dispose on the reader when done and I think that should clean up the connection.