首页 文章

确保主线程等待所有任务完成

提问于
浏览
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值生成一个新任务,并在该List中写出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个文件有机会写出来 .

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

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 ,如果超时则打印进度消息并再次等待......

相关问题