\n <\/td>\n | public<\/span> static<\/span><\/span> void<\/span> MyParallelForEach<\/span><<\/span>T<\/span>><\/span>(<\/span>IEnumerable<\/span><<\/span>T<\/span>><\/span> source<\/span>,<\/span> Action<\/span> <<\/span>T<\/span>><\/span> body<\/span>)<\/span><\/td>\n <\/tr>\n \n <\/td>\n | {<\/span><\/td>\n <\/tr>\n \n <\/td>\n | int<\/span> numProcs<\/span> =<\/span> Environment.<\/span>ProcessorCount;<\/span><\/td>\n <\/tr>\n \n <\/td>\n | int<\/span> remainingWorkItems<\/span> =<\/span> numProcs;<\/span><\/td>\n <\/tr>\n \n <\/td>\n | using<\/span>(<\/span>var<\/span> enumerator<\/span> =<\/span> source.<\/span>GetEnumerator<\/span>(<\/span>)<\/span>)<\/span><\/td>\n <\/tr>\n \n <\/td>\n | {<\/span><\/td>\n <\/tr>\n \n <\/td>\n | using<\/span>(<\/span>ManualResetEvent<\/span> mre<\/span> =<\/span> new<\/span> ManualResetEvent(<\/span>false<\/span>)<\/span>)<\/span><\/td>\n <\/tr>\n \n <\/td>\n | {<\/span><\/td>\n <\/tr>\n \n <\/td>\n | // Create each of the work items.<\/span><\/td>\n <\/tr>\n \n <\/td>\n | for<\/span> (<\/span>int<\/span> p<\/span> =<\/span> 0<\/span>;<\/span> p<\/span> <<\/span> numProcs<\/span>;<\/span> p<\/span>++<\/span>)<\/span> {<\/span><\/td>\n <\/tr>\n \n <\/td>\n | ThreadPool.<\/span>QueueUserWorkItem<\/span>(<\/span>delegate<\/span><\/td>\n <\/tr>\n \n <\/td>\n | {<\/span><\/td>\n <\/tr>\n \n <\/td>\n | // Iterate until there's no more work.<\/span><\/td>\n <\/tr>\n \n <\/td>\n | while<\/span> (<\/span>true<\/span>)<\/span> {<\/span><\/td>\n <\/tr>\n \n <\/td>\n | // Get the next item under a lock,<\/span><\/td>\n <\/tr>\n \n <\/td>\n | // then process that item.<\/span><\/td>\n <\/tr>\n \n <\/td>\n | T<\/span> nextItem<\/span>;<\/span><\/td>\n <\/tr>\n \n <\/td>\n | lock<\/span>(<\/span>enumerator<\/span>)<\/span><\/td>\n <\/tr>\n \n <\/td>\n | {<\/span><\/td>\n <\/tr>\n \n <\/td>\n | if<\/span> (<\/span>!<\/span>enumerator.<\/span>MoveNext<\/span>(<\/span>)<\/span>)<\/span> break<\/span>;<\/span><\/td>\n <\/tr>\n \n <\/td>\n | nextItem<\/span> =<\/span> enumerator.<\/span>Current;<\/span><\/td>\n <\/tr>\n \n <\/td>\n | }<\/span><\/td>\n <\/tr>\n \n <\/td>\n | body(<\/span>nextItem)<\/span>;<\/span><\/td>\n <\/tr>\n \n <\/td>\n | }<\/span><\/td>\n <\/tr>\n \n <\/td>\n | if<\/span> (<\/span>Interlocked.<\/span>Decrement<\/span>(<\/span>ref<\/span> remainingWorkItems)<\/span> ==<\/span> 0<\/span>)<\/span><\/td>\n <\/tr>\n \n <\/td>\n | mre.<\/span>Set<\/span>(<\/span>)<\/span>;<\/span><\/td>\n <\/tr>\n \n <\/td>\n | }<\/span>)<\/span>;<\/span><\/td>\n <\/tr>\n \n <\/td>\n | }<\/span><\/td>\n <\/tr>\n \n <\/td>\n | // Wait for all threads to complete.<\/span><\/td>\n <\/tr>\n \n <\/td>\n | mre.<\/span>WaitOne<\/span>(<\/span>)<\/span>;<\/span><\/td>\n <\/tr>\n \n <\/td>\n | }<\/span><\/td>\n <\/tr>\n \n <\/td>\n | }<\/span><\/td>\n <\/tr>\n \n <\/td>\n | }<\/span><\/td>\n <\/tr>\n <\/table>\n<\/div>\n\n\n <\/div>\n\n <\/div>\n<\/div>\n\n <\/div>\n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |