.net - .NET 4.0中的Parallel.ForEach

标签 .net multithreading parallel-processing task-parallel-library

    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将处于线程级别或任务级别。按照本书的观点,它是在任务级别上的,但是由于一个线程可以执行多个任务,而不是变量在整个程序执行过程中如何保持其值。
我认为应该在线程级别。

有人可以提供有关此方面的见解吗?是否可以提供更多链接,以使我可以更清楚地了解这一概念。

最佳答案

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

因此,在每个任务结束时,任务的结果将传递到Interlocked.Add方法,该方法将masterTotal与该任务的本地总数相加。

令人困惑的部分是这一部分:

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在这里与“任务”操作中的名称相同。

因此,它不是相同的变量,而是相同的名称。

关于.net - .NET 4.0中的Parallel.ForEach,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8910152/

相关文章:

c# - 如何创建一个在体内使用 await 的 Task,其行为与调用 Wait 时的同步版本相同?

c++ - C++中的多线程: The correct way to join threads

java - 显示一年中的最低平均价格,以及该价格的周数以及该价格发生的月份名称

c# - 自定义 Visual Studio 错误

.net - Delphi至.Net格式的字符串转换

linux - 为什么使用 taskset -c 时线程唤醒要快得多

parallel-processing - 何时不使用 MPI

r - R中的doParallel错误:serialize(data,node $ con)错误:写入连接时出错

.net - .net Compact Framework 的第 3 方 UI 组件?

java - 停止与 udp 服务器的线程