C# Parallel.For和Parallel.ForEach学习
来源:互联网 发布:算工资的软件 编辑:程序博客网 时间:2024/05/21 06:27
《精通C#编程(第6版)》598页,“在次线程中访问UI元素”,按照书上的源代码程序总是无响应,百度后发现是线程死锁的原因;
参见
c#+Parallel.ForEach的卡死现象
使用了ThreadPool.QueueUserWorkItem改进书上例子。
3a.如果单个任务执行非常快以致于创建线程的开销远大于在当前线程执行剩余任务的开销,那么任务调度器不会创建其它工作线程,所有的Invoke都在当前线程得以执行,ForEach返回。3b.如果创建线程可能加快任务处理速度,任务调度器会创建工作线程,并在工作线程上安排任务。
4b.在工作线程上执行的Invoke全部被阻塞,等待窗体线程进行处理。
5b.窗体线程执行所有可执行的任务后,等待ForEach返回,但由于其他线程在等待窗体线程处理Invoke,任务不能完成,ForEach无法返回,造成死锁。”
public partial class MainForm : Form { public MainForm() { InitializeComponent(); } private void btnProcessImage_Click(object sender, EventArgs e) { DirectoryInfo dir = new DirectoryInfo(@"d:\samplePicture"); dir.Delete(true); dir = new DirectoryInfo(@"d:\samplePictureParallelForEach"); dir.Delete(true); dir = new DirectoryInfo(@"d:\samplePictureParallelFor"); dir.Delete(true); ThreadPool.QueueUserWorkItem(w => { ProcessImage(); }, null); ThreadPool.QueueUserWorkItem(w => { ProcessImageParallelFor(); }, null); ThreadPool.QueueUserWorkItem(w => { ProcessImageParallelForEach(); }, null); textBox1.AppendText("\r\n"); } private void ProcessImage() { Stopwatch sw = new Stopwatch(); sw.Start(); string[] files = Directory.GetFiles(@"d:\sample", "*.jpg", SearchOption.AllDirectories); string newDir = @"d:\samplePicture"; Directory.CreateDirectory(newDir); foreach(string currentfile in files) { string fileName = Path.GetFileName(currentfile); using (Bitmap bitMap = new Bitmap(currentfile)) { bitMap.RotateFlip(RotateFlipType.Rotate180FlipNone); bitMap.Save(Path.Combine(newDir, fileName)); Invoke((Action)delegate { Text = string.Format("Processing {0} on thread {1}", fileName, Thread.CurrentThread.ManagedThreadId); }); } } sw.Stop(); Invoke((Action)delegate { textBox1.AppendText(string.Format("\r\n正常Foreach循环耗时:{0} ", sw.Elapsed.TotalSeconds.ToString())); }); } //ParallelForEach 并行 private void ProcessImageParallelForEach() { Stopwatch sw2 = new Stopwatch(); sw2.Start(); string[] files = Directory.GetFiles(@"d:\sample", "*.jpg", SearchOption.AllDirectories); string newDir = @"d:\samplePictureParallelForEach"; Directory.CreateDirectory(newDir); Parallel.ForEach (files, currentfile => { string fileName = Path.GetFileName(currentfile); using (Bitmap bitMap = new Bitmap(currentfile)) { bitMap.RotateFlip(RotateFlipType.Rotate180FlipNone); bitMap.Save(Path.Combine(newDir, fileName)); Invoke((Action)delegate { Text = string.Format("Processing {0} on thread {1}", fileName, Thread.CurrentThread.ManagedThreadId); }); } } ); sw2.Stop(); Invoke((Action)delegate { textBox1.AppendText(string.Format("\r\n并行ForEach模式耗时:{0} ", sw2.Elapsed.TotalSeconds.ToString())); }); } //ParallelFor并行 private void ProcessImageParallelFor() { Stopwatch sw3 = new Stopwatch(); sw3.Start(); string[] files = Directory.GetFiles(@"d:\sample", "*.jpg", SearchOption.AllDirectories); string newDir = @"d:\samplePictureParallelFor"; Directory.CreateDirectory(newDir); Parallel.For(0, files.Length, (index) => { string[] filesTemp = Directory.GetFiles(@"d:\sample", "*.jpg", SearchOption.AllDirectories); string fileName = Path.GetFileName( filesTemp[index]); using (Bitmap bitMap = new Bitmap(filesTemp[index])) { bitMap.RotateFlip(RotateFlipType.Rotate180FlipNone); bitMap.Save(Path.Combine(newDir, fileName)); Invoke((Action)delegate { Text = string.Format("Processing {0} on thread {1}", fileName, Thread.CurrentThread.ManagedThreadId); }); } }); sw3.Stop(); Invoke((Action)delegate { textBox1.AppendText(string.Format("\r\n并行For模式耗时:{0} ", sw3.Elapsed.TotalSeconds.ToString())); }); } }
测试结果:
阅读全文
0 0
- C# Parallel.For和Parallel.ForEach学习
- C# 使用Parallel并行开发Parallel.For、Parallel.Foreach实例
- Parallel.For & Parallel.ForEach & Parallel.Invoke
- Task Parallel.For、Parallel.ForEach、Parallel.Invoke
- C#多线程 为多核处理器而生的多线程方法Parallel.For和Parallel.ForEach
- .NET 4.0中的Parallel.For 和 Parallel.ForEach的用法
- C#并行运算 Parallel.Invoke、Parallel.For、Parallel.Foreach性能测试及示例
- Parallel.ForEach
- 平行运算:Parallel.For、Parallel.Foreach的体验式试用
- C# 并行循环Parallel.For
- For parallel
- C# 多线程 Parallel.ForEach 和 ForEach 效率问题研究及理解
- 用Parallel和foreach包玩转并行计算
- Parallel's foreach method
- Parallel.ForEach() 并行循环
- Parallel.ForEach() 并行循环
- 看看Parallel中高度封装的三个方法,Invoke,For和ForEach
- 看看Parallel中高度封装的三个方法,Invoke,For和ForEach
- Spring自动装配Bean的两种方法(—)
- 【我的Android进阶之旅】Android 混淆文件资源分类整理
- 面向对象编程其实很简单——Python 面向对象(初级篇)
- 实时语音视频SDK使用FEC和ARQ实现超低延迟
- HDU 2669 Romantic【扩展欧几里得板子题】
- C# Parallel.For和Parallel.ForEach学习
- 二、配置你的bean
- Java中Synchronized的用法
- DQL、DML、DDL、DCL的概念与区别(转)
- 多条目
- Spring 深入浅出核心技术(三)
- Qt学习记录六
- Capstone训练营7
- rancher 安装