【问题标题】:Ensuring primary thread waits for all Tasks to complete确保主线程等待所有任务完成
【发布时间】:2012-11-14 19:00:39
【问题描述】:

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

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

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

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

因此,在 ProcessXFastFile 方法中,我使用产品代码作为键值创建了一个 Dictionary&lt;string, List&lt;string&gt;&gt;,并将与该键匹配的每个 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));
}

问题是主线程在每个写入产品文件的任务有机会完成写出数据之前就结束了。例如,我使用一个文件作为对照测试,并且知道字典中有大约 450 个唯一键,因此应该写出许多相应的文件。但是,在程序结束之前,只有大约 10 个文件有机会写出。

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

【问题讨论】:

    标签: c# multithreading task-parallel-library task


    【解决方案1】:

    你可以把你得到的所有任务放到一个List&lt;Task&gt;中,而不是仅仅创建它们然后折腾它们,然后使用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,如果超时则打印进度消息并再次等待,等等...

    【讨论】:

    • 不错,这看起来很有希望,我现在就试一试
    • 效果很好。感谢您提供简洁明了的解决方案!
    • 没问题!很高兴我能帮上忙!
    猜你喜欢
    • 2019-10-24
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 2020-03-27
    • 2010-09-20
    相关资源
    最近更新 更多