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

C# 使用ExecuteReaderAsync时,无法将类型DbDataReader隐式转换为MySqlDataReader,c#,mysql,asynchronous,.net-4.5,async-await,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 = n

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

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

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;
}
该函数的调用方式如下

 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);
        }
        );


 }
List=newlist();
列表oParams=新列表();
列表ID=新列表(500);
添加(1);
添加(2);
...
同上(499);
foreach(Id中的int-Id)
{
MySQLReturnReader(“SPCheck”、oParams、oRes=>
{
while(oRes.Read())
{
MyClass=新的MyClass();
oMyClass.Id=Convert.ToInt32(oRes[“Id”]);
omiclass.Name=oRes[“Name”].ToString();
}
添加(myCLASS);
}
);
}
问题是我得到的编译错误是“无法隐式转换类型”System.Threading.Tasks.Task“到”MySql.Data.MySqlClient.MySqlDataReader“。我哪里做错了


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

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


因此,我认为您应该直接使用旧的
ExecuteReader()
,直到您的库在代码中添加对
ExecuteReaderAsync()

的支持为止,您已经:

using (MySqlDataReader oReader = oMySqlCommand.ExecuteReaderAsync())
编译器错误
无法将类型“System.Threading.Tasks.Task”隐式转换为“MySql.Data.MySqlClient.MySqlDataReader”
意味着您需要使用
wait
关键字“展开”ExecuteReaderAsync返回的任务:

using (MySqlDataReader oReader = await oMySqlCommand.ExecuteReaderAsync())
但是请注意,如果您使用的是官方的MySql.Data包,那么这个调用实际上不会异步执行。
MySql.Data
连接器中的
Async
方法不是异步的;它们在网络I/O上阻塞,仅在DB操作完成时返回。(有关更详细的讨论,请参阅。)在MySQL连接器中报告此问题


要获得真正的异步DB操作,您必须等待该错误被修复,或者切换到其他连接器。我一直在开发一个新的、完全异步的连接器,它应该是MySql.Data的替代品;要试用它,请安装;其。

我理解您的答案,但是是否有一种解决方法可以使我的调用异步?@Tommo1977我认为您不能,您不能在不修改库的情况下将同步库变为异步库。您可以始终使用
Task.Run()
来执行同步方法,但这并不是真正的异步(它仍然会阻塞线程)。谢谢。如何调整示例以使用Task.Run()。我知道它不是真正的异步,但它允许同时对存储过程进行多个调用。MySql.Data支持
ExecuteReaderAsync
很长一段时间了(它只是没有正确实现;请参阅我的答案)。OP发布的编译器错误仅仅意味着代码缺少
await
关键字。
using (MySqlDataReader oReader = await oMySqlCommand.ExecuteReaderAsync())