c# - 使用异步查询多个 MySQL 实例 - 分片环境
问题描述
我正在构建一个使用 MVC 对分片 MySQL 环境运行查询的工具。当前工具的工作方式是让用户输入查询,选择他们的数据库,然后选择实例。因此,我可以从中构建连接字符串并将它们添加到列表中并将它们传递给我的查询数据库类中的方法。这很好用,但会很慢,因为它是同步的。
如何将我的同步 foreach 循环转换为异步方法?
以下是我目前从服务器获取数据的方法:
public DataSet getResults(List<string> connstrings, string query)
{
foreach (string con in connstrings)
{
DataSet masterDS = new DataSet();
MySqlConnection conn = new MySqlConnection(con);
try
{
conn.Open();
MySqlCommand cmd = new MySqlCommand(query, conn);
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
masterDS.Merge(ds);
}
catch (MySqlException ex)
{
int errorcode = ex.Number;
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
finally
{
conn.Close();
}
}
Return MasterDS;
}
此外,我不会将结果存储在内存中,而是将它们写入服务器上的文件。
解决方案
老实说,不知道是否DataSet
会喜欢这个,如果这是线程安全的。但这是您可以对 CPU 密集型任务执行的一件事:
public DataSet getResults(List<string> connstrings, string query)
{
var tasks = new List<Task>();
DataSet masterDS = new DataSet();
foreach (string con in connstrings)
{
tasks.Add(Task.Run(() =
{
MySqlConnection conn = new MySqlConnection(con);
try
{
conn.Open();
MySqlCommand cmd = new MySqlCommand(query, conn);
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
// NOTE changes here
da.Fill(masterDS);
}
catch (MySqlException ex)
{
int errorcode = ex.Number;
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
finally
{
conn.Close();
}
});
}
Task.WaitAll(tasks.ToArray());
Return MasterDS;
}
潜在地,您可能想要返回到Merge
. 只有在所有任务完成后才这样做。如果您想变得非常复杂,可以调用Task.ContinueWith
,将每个 DS 添加到并发队列中,然后再使用另一个Task.Run...
,它从该队列中获取并在单个线程上合并 DS,同时仍在填充 DS。所以,等到完成的时候Task.WaitAll
,你就完成了
推荐阅读
- java - 错误消息 400:折叠页眉
- android - 如何通过 StorageVolume 将数据写入 Android 中的 SD 卡?
- excel - 查找列表中许多值的最大值和最小值
- jsp - 如何在没有查询字符串的情况下获取url,如jsp中的stackoverflow
- bitbucket - Bitbucket(拉取请求)评论在更新后被删除
- javascript - 将 forEach 中的当前对象传递给函数
- node.js - MyContract.methods.addData 不适用于 nodejs web3
- java - 为什么不在具有多对一关系的表中记录一个 id?弹簧数据,Liquidbase
- c++ - 无法将动态创建的对象数组从 qml 发送到 c++ 作为方法参数
- python - 如何在python的单个for循环中使用2个索引变量