使用ExecuteReaderAsync时,无法将类型DbDataReader隐式转换为MySqlDataReader

时间:2013-11-18 16:52:04

标签: c# mysql asynchronous .net-4.5 async-await

我有以下函数允许我传入一个对象并用返回的数据填充该对象(如果有的话)。

我修改了这个函数,以便可以异步调用它。

public static async Task<MySqlDataReader> MySQLReturnReader(string sName, List<MySqlParameter> oParameters, Action<MySqlDataReader> fn)
{
    using (MySqlConnection oConn = new MySqlConnection(MasterConn))
    {
        await oConn.OpenAsync();

        using (MySqlCommand oMySqlCommand = new MySqlCommand(sName, oConn))
        {
           oMySqlCommand.CommandType = CommandType.StoredProcedure;

            if (oParameters != null)
            {
                foreach (MySqlParameter oPar in oParameters)
                {
                    oMySqlCommand.Parameters.Add(oPar);
                }
            }

            oMySqlCommand.Connection.Open();

            using (MySqlDataReader oReader = oMySqlCommand.ExecuteReaderAsync())
            {
               fn(oReader);
            }

        }
    }
    return;
}

我的类对象就像;

public class MyClass
{
     public int Id {get;set;}
     public string Name {get;set;}
     ...
}

该功能可以像

一样调用
 List<MyClass> oMyClassList = new List<MyClass>();
 List<MySqlParameter> oParams = new List<MySqlParameter>();

 List<int> Ids = new List<int>(500);
 Ids.Add(1);
 Ids.Add(2);
 ...
 Ids.Add(499);

 foreach(int Id in Ids)
 {
    MySQLReturnReader("SPCheck", oParams, oRes =>
        {
                while (oRes.Read())
                {
                   MyClass oMyClass = new MyClass();                      
                   oMyClass.Id = Convert.ToInt32(oRes["Id"]);                       
                   oMyClass.Name = oRes["Name"].ToString();
                }

                oMyClassList.Add(oMyClass);
        }
        );


 }

问题是我得到'无法隐式转换类型'System.Threading.Tasks.Task'到'MySql.Data.MySqlClient.MySqlDataReader'的编译错误。我哪里错了?

我想以这种方式使用ExecuteReaderAsync,因为调用的存储过程非常复杂,并且更愿意并行运行请求。

2 个答案:

答案 0 :(得分:0)

在您的代码中,您有:

using (MySqlDataReader oReader = oMySqlCommand.ExecuteReaderAsync())

编译器错误Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'MySql.Data.MySqlClient.MySqlDataReader'表示您需要使用await关键字来打开&#34;解包&#34; ExecuteReaderAsync返回的任务:

using (MySqlDataReader oReader = await oMySqlCommand.ExecuteReaderAsync())

但请注意,如果您使用的是官方MySql.Data程序包,则此调用实际上不会异步执行。 Async连接器中的MySql.Data方法不是异步的;它们阻塞网络I / O,仅在DB操作完成时返回。 (有关更详细的讨论,请参阅this question and its top answer。)MySQL bug #70111在MySQL连接器中报告此问题。

要获得真正的异步数据库操作,您必须等到修复该错误,或​​者切换到其他连接器。我一直在开发一个新的完全异步连接器,它应该是MySql.Data的替代品。尝试一下,安装MySqlConnector from NuGet;它的source is at GitHub

答案 1 :(得分:-1)

这很可能表示您使用的库不支持ExecuteReaderAsync(),因此您只需调用从DbCommand继承的默认实现。这就是它返回通用DbDataReader(而不是MySQL特定的)的原因。这也意味着您的代码实际上不是异步的,ExecuteReaderAsync()的默认版本只是ExecuteReader()的同步包装。

所以,我认为您应该直接使用旧版ExecuteReader(),直到您的图书馆添加对ExecuteReaderAsync()的支持。