.NET 4.0 中的 Parallel.ForEach
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将处于线程级别或任务级别。根据本书,它是在任务级别的,但是由于一个线程可以执行多个任务,因此变量如何在程序执行过程中保持其值。 我认为应该是在线程级别。
有人可以提供对此的见解以及可能的更多链接来阅读,我可以在其中更清楚地了解这个概念。
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;
}
This is a piece of code I got from a book. I have a doubt in this.
The variable tasklocaltotal
will be at a thread level or a task level. As per the book it is at task level, but since multiple tasks can be executed by a thread than how come the variable is maintaining its value throughout the execution of the program.
I think it should be at the thread level.
Can someone provide insight on this and possible more links to read where I can get this concept more clear.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
此处使用的 ForEach 的重载 指定最后一个参数是为每个结束的任务调用的操作。
因此,在每个任务结束时,任务的结果都会传递给 Interlocked.Add 方法,该方法会使用该任务的本地总计来递增 masterTotal。
令人困惑的部分是这部分:
只需将其视为(您甚至可以将其写为):
taskLocalTotal 不幸的是这里与任务操作中的名称相同。
所以它不是相同的变量,只是名称相同。
The overload of ForEach that is being used here specifies that the last parameter is an Action that is called for each ended task.
So at the end of each task the task's result is passed to the Interlocked.Add method which increments the masterTotal with that task's local total.
The confusing part is this part:
Just think of it as (you can even write it as):
taskLocalTotal unfortunately has the same name here as in the Task's action.
So it is not the same variable but just the same name.