方案一:

调用线程控制方法.启动: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 = ; j < ; j++)
{
int vSum = ;
this.textBox1.Text += "--->";
for (int i = ; i < ; i++)
{
if (i % == )
{
vSum += i;
}
else
{
vSum -= i;
}
}
this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum);
Thread.Sleep();
}
}
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 = ; j < ; j++)
{
int vSum = ;
this.textBox1.Text += "--->";
for (int i = ; i < ; i++)
{
if (i % == )
{
vSum += i;
}
else
{
vSum -= i;
}
}
this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum);
Thread.Sleep();
}
}
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 == )
{
return false; // 返回false,线程停止
}
else if (this.mTdFlag == )
{
while (mTdFlag != )
{
Thread.Sleep(); // 假暂停;停顿时间越短,越灵敏
if (this.mTdFlag == )
{
return false; // 返回false,线程停止
}
}
}
return true; // 返回true,线程继续
}

3.修改 控制命令 事件:

        private void btn_Stop_Click(object sender, EventArgs e)
{
this.mTdFlag = ;
//mThread.Abort(); // 终止
} private void btn_Suspend_Click(object sender, EventArgs e)
{
this.mTdFlag = ;
//mThread.Suspend(); // 暂停
} private void btn_Resume_Click(object sender, EventArgs e)
{
this.mTdFlag = ;
//mThread.Resume(); // 继续
}

4.在线程运行过程中适当的位置,判断线程是否继续

            mThread = new Thread(() =>
{
try
{
for (int j = ; j < ; j++)
{
int vSum = ;
this.textBox1.Text += "--->";
for (int i = ; i < ; i++)
{
if (i % == )
{
vSum += i;
}
else
{
vSum -= i;
}
if (i % == )
{
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();
}
}
catch (ThreadAbortException ex)
{
Console.WriteLine("ThreadAbortException:{0}", ex.Message);
this.textBox1.Text += ex.Message + "...";
}
finally
{
this.textBox1.Text += "线程已结束";
}
});

在窗体中,解决跨线程访问问题:在窗体构造函数中添加代码:  Control.CheckForIllegalCrossThreadCalls = false;

[http://www.cnblogs.com/CUIT-DX037/]

C# 多线程之线程控制的更多相关文章

  1. Java多线程开发系列之四:玩转多线程(线程的控制2)

    在上节的线程控制(详情点击这里)中,我们讲解了线程的等待join().守护线程.本节我们将会把剩下的线程控制内容一并讲完,主要内容有线程的睡眠.让步.优先级.挂起和恢复.停止等. 废话不多说,我们直接 ...

  2. Java多线程开发系列之四:玩转多线程(线程的控制1)

    在前文中我们已经学习了:线程的基本情况.如何创建多线程.线程的生命周期.利用已有知识我们已经可以写出如何利用多线程处理大量任务这样简单的程序.但是当应用场景复杂时,我们还需要从管理控制入手,更好的操纵 ...

  3. Win32多线程编程(2) — 线程控制

    Win32线程控制只有是围绕线程这一内核对象的创建.挂起.恢复.终结以及通信等操作,这些操作都依赖于Win32操作系统提供的一组API和具体编译器的C运行时库函数.本篇围绕这些操作接口介绍在Windo ...

  4. Java多线程之线程的控制

    Java多线程之线程的控制 线程中的7 种非常重要的状态:  初始New.可运行Runnable.运行Running.阻塞Blocked.锁池lock_pool.等待队列wait_pool.结束Dea ...

  5. java多线程(六)线程控制类

    1.   多线程控制类 为了保证多线程的三个特性,Java引入了很多线程控制机制,下面介绍其中常用的几种: l  ThreadLocal l  原子类 l  Lock类 l  Volatile关键字 ...

  6. Java多线程学习(四)---控制线程

    控制线程 摘要: Java的线程支持提供了一些便捷的工具方法,通过这些便捷的工具方法可以很好地控制线程的执行 1. join线程控制,让一个线程等待另一个线程完成的方法 2. 后台线程,又称为守护线程 ...

  7. C#多线程之线程同步篇3

    在上一篇C#多线程之线程同步篇2中,我们主要学习了AutoResetEvent构造.ManualResetEventSlim构造和CountdownEvent构造,在这一篇中,我们将学习Barrier ...

  8. Java并发1——线程创建、启动、生命周期与线程控制

    内容提要: 线程与进程 为什么要使用多线程/进程?线程与进程的区别?线程对比进程的优势?Java中有多进程吗? 线程的创建与启动 线程的创建有哪几种方式?它们之间有什么区别? 线程的生命周期与线程控制 ...

  9. 06_Java多线程、线程间通信

    1. 线程的概念      1.1多进程与多线程 进程:一个正在执行的程序.每个进程执行都有一个执行顺序,该顺序是一个执行路径,或叫一个控制单元. 一个进程至少有一个线程. 线程:就是进程中的一个独立 ...

随机推荐

  1. IIS备份和还原

    当我们电脑系统有大量的站点和虚拟目录的时候,电脑因为种种原因需要重做系统,那么重装系统后这些站点我们是否只能一个一个的添加,如果有成百上千个站点呢,任务量可想而知,本文将介绍如何备份和还原window ...

  2. CentOS 配置RDP

    XRDP服务器 CentOS安装XRDP实现远程桌面访问: 由于安装的是远程桌面,因此需要安装桌面显示服务:# yum install vnc-server 下面开始配置XRDP服务 l  配置环境: ...

  3. BluetoothSetServiceState 函数

    DWORD BluetoothSetServiceState( HANDLE hRadio, BLUETOOTH_DEVICE_INFO* pbtdi, GUID* pGuidService, DWO ...

  4. #ifdef-#endif的作用及其使用技巧

    电脑程序语句,我们可以用它区隔一些与特定头文件.程序库和其他文件版本有关的代码. 1 2 3 #ifdef语句1 //程序2 #endif 可翻译为:如果宏定义了语句1则程序2. 作用:我们可以用它区 ...

  5. vue 上传二进制图片

    1.前段代码 <el-form-item label="证件照片" prop="idImage"> <input @change='ss' t ...

  6. Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

    1 测试器及其使用 在模板中的 {{}} 可以书写测试器,格式如下 {{ 变量 is 测试器名称  }} 1.1 在python中导入 Jinja2 的模板 from jinja2 import te ...

  7. Ajax 执行流程 有用 一点

    l 1.1使用JavaScript获得浏览器内置的AJAX引擎(XMLHttpRequest对象) l 1.2 通过AJAX引擎确定请求路径和请求参数 l 1.3 通知AJAX引擎发送请求 l AJA ...

  8. 树莓派 Learning 002 必备的操作 --- 08 实现PC端 远程登入 树莓派 --- 法1 远程登入树莓派的命令行状态

    树莓派 必备的操作 - 实现PC端 远程登入 树莓派 - 法1 远程登入树莓派的命令行状态 我的树莓派型号:Raspberry Pi 2 Model B V1.1 装机系统:NOOBS v1.9.2 ...

  9. C#识别图中二维码

    1.在NuGet中添加 ZXing.Net 2.实例代码 /// <summary> /// 识别图中二维码 /// </summary> /// <param name ...

  10. 括号序列(区间dp)

    括号序列(区间dp) 输入一个长度不超过100的,由"(",")","[",")"组成的序列,请添加尽量少的括号,得到一 ...