使用ContinueWith等待任务在列表中完成

时间:2017-04-11 15:23:37

标签: c# multithreading async-await task

更新 添加了缺少的用于添加taskList

的代码

我有一份任务清单,我等着......

var files = Directory.GetFiles(myFilesDirectory);
var listOfTasks = new List<Tasks>();
files.ToList().ForEach(file => {
    var localFile = file // to avoid any closure issue
    listOfTasks.Add(ProcessMyFileTask(localFile));
});
await Task.WhenAll(listOfTasks.ToArray());
Console.WriteLine("All done!");

这里是ProcessMyFileTask

private async Task<List<string>> ProcessMyFileTask(string filePath)
    {
        using (var streamReader = File.OpenText(filePath))
        {
            string line;
            if ((line = await streamReader.ReadLineAsync()) != null)
            {
                return DumpHexInLog(line);
            }
            return null;
        }
    }

处理完所有文件时会显示该消息。但是如果我添加一个延续任务,就像这样......

var files = Directory.GetFiles(myFilesDirectory);
var listOfTasks = new List<Tasks>();
files.ToList().ForEach(file => {
    var localFile = file // to avoid any closure issue
    listOfTasks.Add(ProcessMyFileTask(localFile).ContinueWith(list => 
            ValidateHexDumpsTask(list.Result, localFile)));
});
await Task.WhenAll(listOfTasks.ToArray());
Console.WriteLine("All done!");

然后等待什么任务?我的意思是在"All Done!"完成后ProcessMyFileTask会来吗?或者它会在所有ValidateHexDumpsTask完成之后出现吗?

当我测试它时,它出现在ValidateHexDumpsTask之后,但我不确定是否总会如此,因为这可能是因为某些线程条件等原因。

2 个答案:

答案 0 :(得分:2)

仅在完成ProcessMyFiles方法和ValidateHexDumps时才会完成。

但是,不推荐使用ContinueWith。这是一个低级,危险的API。您应该使用await代替:

var files = Directory.GetFiles(myFilesDirectory);
var listOfTasks = files.Select(ProcessAndValidateAsync);
await Task.WhenAll(listOfTasks);
Console.WriteLine("All done!");


async Task ProcessAndValidateAsync(string file)
{
  var list = await ProcessMyFileTask(localFile);
  ValidateHexDumps(list, localFile);
}

答案 1 :(得分:0)

WhenAll在每个项目上完成运行时,

ValidateHexDumps将会完成。

ContinueWith返回Task,表示延续的完成,而不是完成继续的任务。