2017-04-11 72 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表示完成延續,而不是完成它是延續的任務。