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())