2

我正在编写一个 C# 控制台应用程序,并且遇到一个问题,即主线程在所有衍生的任务有机会完成之前关闭。一般程序流程如下所示:

该程序将目录路径作为命令行参数。然后它遍历该目录中与特定扩展名匹配的每个文件,并为每个匹配文件生成一个新任务以打开并分析该文件:

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

这些文件中的每一个都包含大量对应于唯一产品密钥的 CSV 值。例如,一个文件可能包含 100 万个 CSV 行和 400 个唯一的产品密钥。该程序的重​​点是根据产品密钥对所有行进行排序,然后根据密钥将它们写回单个文件。

因此,在 ProcessXFastFile 方法中,我Dictionary<string, List<string>>使用产品代码作为键值创建一个,并将与该键匹配的每个 CSV 行添加到相应的列表中。

排序完成后,我遍历字典并为每个 Key 值生成一个新任务,并在该列表中写出 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 的任务有机会完成写出它们的数据之前就结束了。例如,我使用一个文件作为控制测试,并且知道字典中有大约 450 个唯一键,因此应该写出许多相应的文件。但是,在程序结束之前,只有大约 10 个文件有机会写出。

如何确保我的程序保持足够长的时间以完成所有任务?任何帮助表示赞赏。

4

1 回答 1

5

你可以把你得到的所有任务都放到 aList<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 回答