C#多线程之线程控制详解
本文为大家分享了C#多线程之线程控制,供大家参考,具体内容如下
方案一:
调用线程控制方法.启动:Thread.Start();停止:Thread.Abort();暂停:Thread.Suspend();继续:Thread.Resume();
private void btn_Start_Click(object sender, EventArgs e) { mThread.Start(); // 开始 } private void btn_Stop_Click(object sender, EventArgs e) { mThread.Abort(); // 终止 } private void btn_Suspend_Click(object sender, EventArgs e) { mThread.Suspend(); // 暂停 } private void btn_Resume_Click(object sender, EventArgs e) { mThread.Resume(); // 继续 }
线程定义为:
mThread = new Thread(() => { try { for (int j = 0; j < 20; j++) { int vSum = 0; this.textBox1.Text += "--->"; for (int i = 0; i < 100000000; i++) { if (i % 2 == 0) { vSum += i; } else { vSum -= i; } } this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum); Thread.Sleep(1000); } } catch (ThreadAbortException ex) { Console.WriteLine("ThreadAbortException:{0}", ex.Message); } });
值得注意的是: 通过 Thread.Abort() 停下来的线程(或自行运行结束的线程),都无法直接通过 Thread.Start() 方法再次启动,必须重新创建一个线程启动。
所以,“开始按钮”事件应为:
private void btn_Start_Click(object sender, EventArgs e) { // 定义线程 mThread = new Thread(() => // Lambda 表达式 { try { for (int j = 0; j < 20; j++) { int vSum = 0; this.textBox1.Text += "--->"; for (int i = 0; i < 100000000; i++) { if (i % 2 == 0) { vSum += i; } else { vSum -= i; } } this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum); Thread.Sleep(1000); } } catch (ThreadAbortException ex) { Console.WriteLine("ThreadAbortException:{0}", ex.Message); } }); mThread.Start(); // 开始 }
此外,对于 Thread.Suspend() 和 Thread.Resume() 方法,微软已经将其标记为过时:
Thread.Suspend has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202(Thread.Suspend 已被否决。请使用系统中的其他类线程,如监视器、互斥体、事件和信号量,以同步线程或保护资源。http://go.microsoft.com/fwlink/?linkid=14202)
因为,无法判断当前挂起线程时它正在执行什么代码。如果在安全权限评估期间挂起持有锁的线程,则 AppDoamin 中的其它线程可能被阻止。如果在线程正执行构造函数时挂起它,则 AppDomain 中尝试使用该类的其它线程将被阻止。这样容易发生死锁。
方案二:
在 线程运行过程中 适当的位置(如某个完整的功能/命令后)判断是否要继续线程,再决定线程的命运。
1.定义一个全局变量:
int mTdFlag = 0; // 1:正常运行;2:暂停;3:停止
2. 定义一个判断方法:
bool WaitForContinue() { if (this.mTdFlag == 3) { return false; // 返回false,线程停止 } else if (this.mTdFlag == 2) { while (mTdFlag != 1) { Thread.Sleep(200); // 假暂停;停顿时间越短,越灵敏 if (this.mTdFlag == 3) { return false; // 返回false,线程停止 } } } return true; // 返回true,线程继续 }
3.修改 控制命令 事件:
private void btn_Stop_Click(object sender, EventArgs e) { this.mTdFlag = 3; //mThread.Abort(); // 终止 } private void btn_Suspend_Click(object sender, EventArgs e) { this.mTdFlag = 2; //mThread.Suspend(); // 暂停 } private void btn_Resume_Click(object sender, EventArgs e) { this.mTdFlag = 1; //mThread.Resume(); // 继续 }
4.在线程运行过程中适当的位置,判断线程是否继续
mThread = new Thread(() => { try { for (int j = 0; j < 20; j++) { int vSum = 0; this.textBox1.Text += "--->"; for (int i = 0; i < 100000000; i++) { if (i % 2 == 0) { vSum += i; } else { vSum -= i; } if (i % 10000000 == 0) { this.textBox1.Text += "."; } if (!WaitForContinue()) // 返回 false 则,停止 { break; //return; } } this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum); if (!WaitForContinue()) // 返回 false 则,停止 { break; // return; } Thread.Sleep(1000); } } catch (ThreadAbortException ex) { Console.WriteLine("ThreadAbortException:{0}", ex.Message); this.textBox1.Text += ex.Message + "..."; } finally { this.textBox1.Text += "线程已结束"; } });
在窗体中,解决跨线程访问问题:在窗体构造函数中添加代码: Control.CheckForIllegalCrossThreadCalls = false;
您可能感兴趣的文章:
- iOS 开发 多线程详解之线程生命周期控制
- iOS 开发 多线程详解之NSThread线程通信的操作与控制
- Linux入门:多线程编程之线程控制
- Java多线程开发系列之四:玩转多线程(线程的控制1)
- 第二篇 多线程的使用——中断线程详解(Interrupt)
- Java多线程-线程关键字、方法详解
- boost库中thread多线程详解5——谈谈线程中断
- 应用select 函数控制多线程中子线程结束方法
- 多线程_线程控制之休眠线程
- 多线程(三)线程控制之后台线程
- 【Boost】boost库中thread多线程详解5——谈谈线程中断
- (三) Java多线程详解之线程范围内共享变量及ThreadLocal类使用
- 【Boost】boost库中thread多线程详解12——线程的分离与非分离
- Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解
- Java —— 多线程笔记 一、线程创建、启动、生命周期、线程控制
- linux 多线程的线程控制和线程通信
- 多线程入门-第五章-线程的调度与控制之yield
- Java多线程(二)、线程的生命周期和状态控制
- C#多线程、跨线程与线程安全的示例详解
- 多线程(二)线程控制