私は、いくつかの並列データ処理とMySQLの使用でアプリケーションを開発しようとしています。ここで私はこの断片から並列データ処理で情報が混乱する
public ConcurrentDictionary<string, Info> GetDatabaseForCurrentDay(System.DateTime day)
{
string[] date = day.ToShortDateString().Split('.');
string sqlQuery = "SELECT * FROM testtable WHERE Date ='" + date[2] + "-" + date[1] + "-" + date[0] + "';";
ConcurrentDictionary<string, Info> info = new ConcurrentDictionary<string, Info>();
Info[] dayInfo = null;
Parallel.ForEach(ReadData(ConnectionString, sqlQuery), data =>
{
int num = 2;
string[] dataPieces = data.Split(new char[] { ',' }, num);
FileHelpers.FileHelperEngine<Info> engine = new FileHelpers.FileHelperEngine<Info>();
dayInfo = engine.ReadString(dataPieces[1], int.MaxValue);
info.TryAdd(dataPieces[0], dayInfo[0]);
});
return info;
}
別に問題に遭遇したコードの一部であり、それはループParallel.ForEach
の引数を提供するので、機能ReadData(ConnectionString, sqlQuery)
は、また、上述されている価値があります。
public IEnumerable<string> ReadData(string connectionString, string queryString)
{
using (MySqlConnection conn = new MySqlConnection(connectionString))
{
using (MySqlCommand comm = new MySqlCommand(queryString, conn))
{
conn.Open();
string command2 = "USE testdatabase;";
MySqlCommand commandUse = new MySqlCommand(command2, conn);
commandUse.ExecuteNonQuery();
comm.CommandTimeout = 0;
MySqlDataReader reader = comm.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
StringBuilder sb = new StringBuilder();
sb.Append(reader.GetString(0) + ",");
sb.Append(reader.GetDateTime(1).ToString("yyyy-MM-dd") + ",");
sb.Append(reader.GetDouble(2).ToString().Replace(',', '.') + ",");
sb.Append(reader.GetDouble(3).ToString().Replace(',', '.') + ",");
sb.Append(reader.GetDouble(4).ToString().Replace(',', '.') + ",");
sb.Append(reader.GetDouble(5).ToString().Replace(',', '.') + ",");
sb.Append(reader.GetUInt64(6) + ",");
sb.Append(reader.GetDouble(7).ToString().Replace(',', '.'));
yield return sb.ToString();
}
}
}
}
}
ここで、問題に戻りましょう。コードはコンパイルされ、動作しますが、結果は正しくありません。私はConcurrentDictionary
に間違った値のキーが含まれていることに気付きました。つまり、info.TryAdd(dataPieces[0], dayInfo[0])
はあるスレッドのキーと別のスレッドの値を挿入する可能性があり、データが破損する可能性があります。私はこの動作が並列処理の後退であることを理解していますが、この方法は省略できません。私はこの問題を解決するためにさまざまな方法を試しましたが、何も問題なく、データはまだ間違っていました。このコードの実行速度を維持してデータを保存するこの問題に対する解決策はありますか?
だけ明確にする:どのように正確にループ範囲からそのデータを取得するには?デリゲートを使用する場合、同じ問題の別のコピーではありませんか? – cool
'dataPieces'で行ったように、既存のデリゲート内で' dayInfo'を宣言して、そのスコープにローカルにする必要があります。 – Tim
修正コードのスニペットで回答を更新します。また、私は 'dayInfo'への参照が毎回新しい配列で上書きされ続けることを明確にしたかったのです。これは' Info [] 'の同じインスタンス内の値ではありません。私が記述したようにコードを変更しても、Info []のインスタンスが多少生成されるわけではなく、新しい 'Info []'変数への参照が分かれています。 – Tim