DataTable
2つの異なるスレッドからを変更することはできません。エラーになります。スレッドセーフになろうとはしませんDataTable
。だから:そうしないでください。これは1つのスレッドから実行するだけです。ほとんどの場合、IOによって制限されているため、ストリームとして単一のスレッドで実行する必要があります。テキストデータを処理しているようです。あなたはおそらくfor行を持っているようですか?まあ、それはここでは非常に悪いです:string[]
File.ReadAllLines()
- すべてを強制的にメモリにロードします
- すべてがメモリにロードされるのを待つ必要があります
- CSVは複数行形式です。1行==1行であるとは限りません。
コードプロジェクトのCsvReaderのようなものを使用する必要がありますが、一度に1行だけを使用する場合でも、StreamReaderを使用してください。
using(var file = File.OpenText(path)) {
string line;
while((line = file.ReadLine()) != null) {
// process this line
alResult = CSVParser(line, txtDelimiter, txtQualifier);
for (int i = 0; i < alResult.Count; i++)
{
drRow[i] = alResult[i];
}
dtResult.Rows.Add(drRow);
}
}
を使用するとこれは速くなりませんParallel
ので、私はそうしようとはしていません。ここでのボトルネックはIOです。ロックはオプションですが、大したことにはなりません。
alResult
無関係ですが、ループ内で宣言されていないことに気付きました。つまり、元のコードalResult
には、すべてのループ反復間で共有されるキャプチャされた変数が含まれています。つまり、各行はすでにひどく上書きされています。
編集:Parallel
ファイルから1,000,000行を読み取ることに関係がない理由の図:
アプローチ1:を使用ReadAllLines
してラインをロードし、次にを使用してラインParallel
を処理します。これには、物理ファイルIOの[固定時間]がかかり、並列化されます。CPUの作業は最小限で、基本的に[固定時間]を費やしました。ただし、多くのスレッドオーバーヘッドとメモリオーバーヘッドを追加し、すべてのファイルがロードされるまで開始することさえできませんでした。
アプローチ2:ストリーミングAPIを使用します。各行を1行ずつ読み取ります-各行を処理して追加します。ここでのコストは基本的に再びです:ファイルをロードするための実際のIO帯域幅の[固定時間]。だが; これで、スレッドのオーバーヘッド、同期の競合、割り当てる巨大なメモリがなくなり、すぐにテーブルの入力を開始します。
アプローチ3:本当に必要な場合、3番目のアプローチはリーダー/ライターキューで、1つの専用スレッド処理ファイルIOと行のエンキューを行い、2つ目はを実行しDataTable
ます。率直に言って、これははるかに可動部分であり、2番目のスレッドはその時間の95%をファイルからのデータの待機に費やします。アプローチ2に固執する!