2017-04-11 50 views
-1

更新 添加缺少的代码完成在任务列表等待任务在列表中与ContinueWith

我有任务的列表,我等待着上增加..

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!"); 

然后会等待什么任务?我的意思是在所有的ProcessMyFileTask完成后,​​会来吗?还是在所有ValidateHexDumpsTask都完成之后呢?

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

+0

第一点:你不需要'localFile = file'。在这种情况下'file'是lambda表达式的一个参数。它没有捕获任何其他东西。 –

+0

接下来,不清楚你在哪里填充'listOfTasks'。当我们只能看到伪代码时,很难提供帮助。请改为提供[mcve]。 (当然,它们不一定是真正的文件 - 只是字符串可以......) –

+2

这仍然是伪代码 - 由于forEach不是'ForEach',它不会编译。请再次提供[mcve]。 –

回答

2

只有当ProcessMyFiles方法和ValidateHexDumps都完成后,它才会完成。

但是,不建议使用ContinueWith。这是一个低级的,危险的API。您应该使用await代替:当ValidateHexDumps已经完成对每个项目的运行

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); 
} 
+0

不; 'ContinueWith'返回一个代表继续的新任务。 –

+1

['ContinueWithW''很危险](http://blog.stephencleary.com/2013/10/continuewith-is-dangerous-too.html),因为['StartNew'很危险](http:// blog.stephencleary.com/2013/08/startnew-is-dangerous.html):总之,1)它不理解'async'; 2)它使用除“TaskScheduler.Default”之外的默认调度程序; 3)它没有适合异步任务的默认选项('DenyChildAttach')。 –

0

WhenAll将完成。

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