2

C# コンソール アプリを作成していますが、生成されたすべてのタスクが完了する前にプライマリ スレッドが閉じるという問題があります。一般的なプログラム フローは次のようになります。

このプログラムは、ディレクトリへのパスをコマンド ライン パラメータとして受け取ります。次に、特定の拡張子に一致するそのディレクトリ内のすべてのファイルを反復処理し、一致する各ファイルに対して新しいタスクを生成して、そのファイルを開いて分析します。

Directory.GetFiles(directoryPath).ToList<string>().Where(x => Path.GetExtension(x) == ".xfast").ToList().ForEach(x => ProcessXFastFile(x));

これらの各ファイルには、一意のプロダクト キーに対応する多数の CSV 値が含まれています。たとえば、1 つのファイルに 100 万行の CSV 行と 400 個の一意のプロダクト キーが含まれているとします。プログラムのポイントは、プロダクト キーに基づいてすべての行を並べ替え、キーに基づいて個々のファイルに書き戻すことです。

そのため、ProcessXFastFile メソッドではDictionary<string, List<string>>、製品コードをキー値として使用して を作成し、そのキーに一致する各 CSV 行を対応するリストに追加します。

並べ替えが完了したら、辞書を繰り返し処理し、キー値ごとに新しいタスクを生成して、そのリストに CSV 行を書き出します。

foreach (KeyValuePair<string, List<string>> entry in productDictionary) {
    string writePath = String.Format(@"{0}\{1}-{2}.txt", directoryPath, hour, entry.Key);
    List<string> quotes = entry.Value;
    Task writeFileTask = Task.Factory.StartNew(() => WriteProductFile(writePath, quotes));
}

問題は、WriteProductFile へのこれらの各タスクがデータの書き込みを完了する前に、プライマリ スレッドが終了することです。たとえば、1 つのファイルをコントロール テストとして使用し、ディクショナリに最大 450 個の一意のキーがあることを知っているので、対応するファイルが多数書き出されるはずです。ただし、プログラムが終了する前に書き出す機会があるのは約 10 ファイルだけです。

すべてのタスクが完了するのに十分な時間、プログラムを存続させるにはどうすればよいですか? どんな助けでも大歓迎です。

4

1 に答える 1

5

List<Task>タスクを作成して投げるだけでなく、取得したすべてのタスクを に入れ、を使用しTask.WaitAll()て完了を待つことができます。

var tasks = new List<Task>();

foreach (KeyValuePair<string, List<string>> entry in productDictionary) {
    string writePath = String.Format(@"{0}\{1}-{2}.txt", directoryPath, hour, entry.Key);
    List<string> quotes = entry.Value;

    // add task to list
    tasks.Add(Task.Factory.StartNew(() => WriteProductFile(writePath, quotes)));
}

// now wait for all tasks to finish, you'd also want to handle  exceptions of course.
Task.WaitAll(tasks.ToArray());

には多くのバリエーションがありWaitAll()、(上記のように) 無期限に待機するか、 を待機し、TimeSpanタイムアウトの場合は進行状況メッセージを出力して再度待機することができます...

于 2012-11-14T19:02:45.370 に答える