首页 新闻 会员 周边

TPL并行编程问题(Parallel.ForEach)

0
悬赏园豆:10 [已解决问题] 解决于 2015-04-02 10:45

 完整代码,是CSDN上的例子:网址:http://msdn.microsoft.com/zh-cn/library/ff477033(v=vs.110).aspx

例子中的红色代码是什么意思????

 

 

  1 namespace 深入理解C_Sharp
  2 {
  3     class Program
  4     {
  5         static void Main(string[] args)
  6         {
  7             try
  8             {
  9                 TraverseTreeParallelForEach(@"C:\Program Files", (f) =>
 10                 {
 11                     // Exceptions are no-ops.
 12                     try
 13                     {
 14                         // Do nothing with the data except read it.
 15                         byte[] data = File.ReadAllBytes(f);
 16                     }
 17                     catch (FileNotFoundException) { }
 18                     catch (IOException) { }
 19                     catch (UnauthorizedAccessException) { }
 20                     catch (SecurityException) { }
 21                     // Display the filename.
 22                     Console.WriteLine(f);
 23                 });
 24             }
 25             catch (ArgumentException)
 26             {
 27                 Console.WriteLine(@"The directory 'C:\Program Files' does not exist.");
 28             }
 29 
 30 
 31             Console.ReadKey();
 32         }
 33         public static void TraverseTreeParallelForEach(string root, Action<string> action)
 34         {
 35             //Count of files traversed and timer for diagnostic output
 36             int fileCount = 0;
 37             var sw = Stopwatch.StartNew();
 38 
 39             // Determine whether to parallelize file processing on each folder based on processor count.
 40             int procCount = System.Environment.ProcessorCount;
 41 
 42             // Data structure to hold names of subfolders to be examined for files.
 43             Stack<string> dirs = new Stack<string>();
 44 
 45             if (!Directory.Exists(root))
 46             {
 47                 throw new ArgumentException();
 48             }
 49             dirs.Push(root);
 50 
 51             while (dirs.Count > 0)
 52             {
 53                 string currentDir = dirs.Pop();
 54                 string[] subDirs = { };
 55                 string[] files = { };
 56 
 57                 try
 58                 {
 59                     subDirs = Directory.GetDirectories(currentDir);
 60                 }
 61                 // Thrown if we do not have discovery permission on the directory.
 62                 catch (UnauthorizedAccessException e)
 63                 {
 64                     Console.WriteLine(e.Message);
 65                     continue;
 66                 }
 67                 // Thrown if another process has deleted the directory after we retrieved its name.
 68                 catch (DirectoryNotFoundException e)
 69                 {
 70                     Console.WriteLine(e.Message);
 71                     continue;
 72                 }
 73 
 74                 try
 75                 {
 76                     files = Directory.GetFiles(currentDir);
 77                 }
 78                 catch (UnauthorizedAccessException e)
 79                 {
 80                     Console.WriteLine(e.Message);
 81                     continue;
 82                 }
 83                 catch (DirectoryNotFoundException e)
 84                 {
 85                     Console.WriteLine(e.Message);
 86                     continue;
 87                 }
 88                 catch (IOException e)
 89                 {
 90                     Console.WriteLine(e.Message);
 91                     continue;
 92                 }
 93 
 94                 // Execute in parallel if there are enough files in the directory.
 95                 // Otherwise, execute sequentially.Files are opened and processed
 96                 // synchronously but this could be modified to perform async I/O.
 97                 try
 98                 {
 99                     if (files.Length < procCount)    //如果文件夹下的文件小于CPU
100                     {
101                         foreach (var file in files)
102                         {
103                             action(file);
104                             fileCount++;
105                         }
106                     }
107                     else                             //如果文件夹下的文件大于CPU数量,就并行执行
108                     {
109                         Parallel.ForEach(files, () => 0, (file, loopState, localCount) =>
110                         {
111                             action(file);
112                             return (int)++localCount;
113                         },
114                                          (c) =>
115                                          {
116                                              Interlocked.Add(ref fileCount, c);
117                                          });
118                     }
119                 }
120                 catch (AggregateException ae)
121                 {
122                     ae.Handle((ex) =>
123                     {
124                         if (ex is UnauthorizedAccessException)
125                         {
126                             // Here we just output a message and go on.
127                             Console.WriteLine(ex.Message);
128                             return true;
129                         }
130                         // Handle other exceptions here if necessary...
131 
132                         return false;
133                     });
134                 }
135 
136                 // Push the subdirectories onto the stack for traversal.
137                 // This could also be done before handing the files.
138                 foreach (string str in subDirs)   //文件下的文件处理完之后,移除文件夹
139                     dirs.Push(str);
140             }
141 
142             // For diagnostic purposes.
143             Console.WriteLine("Processed {0} files in {1} milleseconds", fileCount, sw.ElapsedMilliseconds);
144         }
145 
146     }
147 }
荣码一生的主页 荣码一生 | 初学一级 | 园豆:163
提问于:2014-09-13 21:31
< >
分享
最佳答案
1
//
        // 摘要: 
        //     对 System.Collections.IEnumerable 执行具有线程本地数据的 foreach(在 Visual Basic 中为 For
        //     Each)操作,其中可能会并行运行迭代,而且可以监视和操作循环的状态。
        //
        // 参数: 
        //   source:
        //     可枚举的数据源。
        //
        //   localInit:
        //     用于返回每个任务的本地数据的初始状态的函数委托。
        //
        //   body:
        //     将为每个迭代调用一次的委托。
        //
        //   localFinally:
        //     用于对每个任务的本地状态执行一个最终操作的委托。
        //
        // 类型参数: 
        //   TSource:
        //     源中数据的类型。
        //
        //   TLocal:
        //     线程本地数据的类型。
        //
        // 返回结果: 
        //     包含有关已完成的循环部分的信息的结构。
        //
        // 异常: 
        //   System.ArgumentNullException:
        //     source 参数为 null。-或- body 参数为 null。-或- localInit 参数为 null。-或- localFinally
        //     参数为 null。
        //
        //   System.AggregateException:
        //     包含在所有线程上引发的全部单个异常的异常。
        public static ParallelLoopResult ForEach<TSource, TLocal>(IEnumerable<TSource> source, Func<TLocal> localInit, Func<TSource, ParallelLoopState, TLocal, TLocal> body, Action<TLocal> localFinally);

然后你对照看看:

 Parallel.ForEach(files, () => 0, (file, loopState, localCount) =>
                    {
                        action(file);
                        return ++localCount;
                    },
                        c => { Interlocked.Add(ref fileCount, c); });

不就明白的

收获园豆:10
Halower | 小虾三级 |园豆:1723 | 2014-09-13 21:51
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册