2
private static Int64 DirectoryBytes(String path) 
    { 
     var files = Directory.EnumerateFiles(path); 
     Int64 masterTotal = 0; 
     ParallelLoopResult result = Parallel.ForEach<String, Int64>(
     files, 
     () => 
     { // localInit: Invoked once per task at start 
      // Initialize that this task has seen 0 bytes 
      return 0; // Set taskLocalTotal initial value to 0 
     }, 
     (file, loopState, index, taskLocalTotal) => 
     { // body: Invoked once per work item 
      // Get this file's size and add it to this task's running total 
      Int64 fileLength = 0; 
      FileStream fs = null; 
      try 
      { 
       fs = File.OpenRead(file); 
       fileLength = fs.Length; 
      } 
      catch (IOException) { /* Ignore any files we can't access */ } 
      finally { if (fs != null) fs.Dispose(); } 
      return taskLocalTotal + fileLength; 
     }, 
     taskLocalTotal => 
     { // localFinally: Invoked once per task at end 
      // Atomically add this task's total to the "master" total 
      Interlocked.Add(ref masterTotal, taskLocalTotal); 
     }); 
     return masterTotal; 
    } 

这是我从一本书中得到的一段代码。我对此有疑问。 变量tasklocaltotal将处于线程级别或任务级别。按照本书的规定,它处于任务级别,但由于线程可以执行多个任务,而不是在变量执行过程中变量如何保持其值。 我认为它应该在线程级别。Parallel.ForEach in .NET 4.0

有人可以提供有关这方面的见解和可能的更多链接来阅读,我可以更清楚地理解这个概念。

回答

1

The overload of ForEach这里使用的是指定最后一个参数是为每个结束任务调用的Action。

因此,在每个任务结束时,任务的结果将传递给Interlocked.Add方法,该方法使用该任务的本地总计增加m​​asterTotal。

混乱的部分是这样的部分:

taskLocalTotal => 
{ 
    // localFinally: Invoked once per task at end 
    // Atomically add this task's total to the "master" total 
    Interlocked.Add(ref masterTotal, taskLocalTotal); 
} 

只是把它看作(你甚至可以把它写成):

x => 
{ 
    // localFinally: Invoked once per task at end 
    // Atomically add this task's total to the "master" total 
    Interlocked.Add(ref masterTotal, x); 
} 

taskLocalTotal遗憾的是这里具有相同的名称作为任务的行动。

所以它不是同一个变量,而是同名。

+0

非常感谢Erno的清理工作。 – Vabs 2012-01-19 06:08:44

+0

@Vabs - 没问题。顺便说一下,您是否注意到我的答案链接到的MSDN页面包含几乎完全相同的代码? – 2012-01-19 07:16:23

+0

是的。我做到了。本书可能使用MSDN代码示例作为生成示例的基础。 – Vabs 2012-01-19 12:05:44