我有以下函数允许我传入一个对象并用返回的数据填充该对象(如果有的话)。
我修改了这个函数,以便可以异步调用它。
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,因为调用的存储过程非常复杂,并且更愿意并行运行请求。
答案 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()
的支持。