C#中如何安全的终止线程Thread线程

微软的文档中不建议以Abort的方式终止线程。比如终止线程的瞬间,FileStream没有释放,会出现问题,等等。
Framework4.0提供了标准取消模式:协作式取消(Cooperative Cancellation),工作线程会定期检查终止线程的标识。取消的时候,协作类中设置这个标识,然后等待工作线程响应。BackgroundWorker类中有类似的标识,可进行对比。
Demo 1:BackgroundWorker类
using System.Collections.G
using System.L
using System.T
using System.T
using System.ComponentM
namespace BackgroundWorkerDemo
class Program
static BackgroundW //namespace是 ComponentModel
static void Main(string[] args)
bw = new BackgroundWorker
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
bw.DoWork += bw_DoW //将方法挂载到DoWork
bw.RunWorkerCompleted += bw_RunWorkerC
bw.RunWorkerAsync();
Console.ReadLine();
if (bw.IsBusy)
bw.CancelAsync();
static void bw_DoWork(object sender, DoWorkEventArgs e)
Console.ForegroundColor = ConsoleColor.R
Console.WriteLine(e.Argument);
Console.ResetColor();
int i = 0;
while(true)
if (bw.CancellationPending)
e.Cancel =
bw.ReportProgress(i);
Thread.Sleep(100);
Console.WriteLine("DoWork progress: " + i.ToString());
if (i == 5) //可以在工作线程中退出
e.Cancel =
static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
if (e.Cancelled)
Console.WriteLine("you canceled,the progress quits");
else if (e.Error != null)
Console.WriteLine("Worker exception:" + e.Error.ToString());
Console.WriteLine("Complete :" + e.Result);
Demo 2 :开启启两个线程,分别向对应文本框中添加信息
private void button4_Click(object sender, EventArgs e)// 线程的终止,不建议使用Abort
//第一种方法:Abort 终止线程
//if (AddThread.IsAlive && AddThread != null)
AddThread.Abort();
//if (AddThread2nd.IsAlive && AddThread2nd != null)
AddThread2nd.Abort();
//第二种方法
canceler.Cancel();
canceler2nd.Cancel();
canceler.Token.Register(() =&
MessageBox.Show("工作线程被终止");
Thread1st =
AddThread2nd =
}有一个问题,快速点击start和stop,线程停止没有问题,但是有时候却只开启了一个线程。可能是因为IsCancellationRequested的值没有及时更新为false。
参考https://blog.gkarch.com/threading/part3.html中第4部分的内容,写个线程终止类,代码如下:
class RulyCanceler
readonly object _locker = new object();
bool cancelRequest =
bool IsCancellationRequest
lock (_locker)
return cancelR
public void Cancel()
lock (_locker)
cancelRequest =
public void Resume()
cancelRequest =
public void ThrowIfCancellationRequested()
if (IsCancellationRequest)
throw new OperationCanceledException();
while (true)
canceler.ThrowIfCancellationRequested();
Thread.Sleep(10);
AddHandleNew(i);
catch (OperationCanceledException)
canceler.Resume();
}Resume需要放在catch(OperationCanceledException)中,也就是说catch到取消事件后,要将类中的取消标记置为false。这样才能避免反复点击start和stop出问题。
C# winform删除线程和退出程序方法
退出C# WinForm程序有很多方法,如:this.Close();
Application.Exit();
Application.ExitThread();
System.Environme...
C# 线程结束方法
C# 线程结束,thread.IsBackground =
C#多线程中子线程快速终止的几个处理办法
因项目需要,采用了多线程方案,其中主线程负责界面处理(如显示数据、与用户交互等),子线程负责读写串口(发送命令、读取数据)。但是,由于使用多线程的经验较少,对于关闭子线程的问题上走了一些弯路,在此留文...
C#为什么不能强行终止线程
不知道是c#设计疏忽还是我没找到方对,.net一直无法强行线程子线程的操作不知道大家注意没有,如果子线程里有 死循环(有时间必须用循环)或子线程在进行一个阻塞式的操作,如影响队列里的消息,那么不能主线...
如何正确停止一个线程
首先肯定是不能用Thread的stop()方法的,因为此方法是非常不安全的,而且已经被废弃了,那么在这里就给出一种官方的推荐方案。
private static Thread mT
...
一、四种方式
1、线程自然return返回。
2、调用 _endthreadex()函数或 ExitThread()函数。
3、在同一个进程的另一个线程中调用 Termi...
退出线程可以有四种方法:1.线程函数的return返回(最好这样):  其中用线程函数的return返回, 而终止线程是最安全的, 在线程函数return返回后, 会清理函数内申请的类对象, 即调用这...
该程序是我写的博客“一起talk &em&C&/em&栗子吧(第一百零九回:&em&C&/em&语言实例--&em&线程&/em&创建与&em&结束&/em&二)”的配套程序,共享给大家使用
如何终止线程的运行(C/C++)
想要终止线程的运行,可以使用以下方法:
1、线程函数返回(最好使用该方法)。
2、通过调用ExitThread函数,线程将自行撤消(最好不使用该方法)。
终止线程的三种方法 有三种方法可以使终止线程。
使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
使用stop方法强行终止线程(这个方法不推荐使用,因为st...
没有更多推荐了,C#基础:使用Thread创建线程_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&100W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
C#基础:使用Thread创建线程
&&C#基础:使用Thread创建线程
阅读已结束,下载本文需要
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
加入VIP
还剩4页未读,
定制HR最喜欢的简历
你可能喜欢C#终止线程实例
子线程里有循环,如何立即终止线程
private void button1_Click(object sender, EventArgs e)
& label10.Text = &正在打开目标地址,请稍后..&;
& label10.Refresh();
& button1.Enabled =
& isAbort =
& thread2 = new Thread(post);
& thread2.Start();
&span id=&more-682&&&/span&
/// &summary&
/// 回帖操作
/// &/summary&
private void post()
& //这里是循环回帖
& for(...)
& if (isAbort)
//终止线程
private void button2_Click(object sender, EventArgs e)
& //停止工作
& isAbort =
& button1.Enabled =
& webBrowser.Visible =
& label10.Text = &停止运行&;
& label10.Refresh();
& MessageBox.Show(&已经是停止状态&);
摘自 https://www.xssxss.com/fuck/682.xss关闭线程Thread&[C#]
最近写的一个程序,关闭主程序时,发现进程里总有一个.exe文件。
研究后发现如果程序退出的时候不关闭线程,那么线程就会一直的存在,但是大多启动的线程都是局部变量,不能一一的关闭,如果调用Thread.CurrentThread.Abort()方法关闭主线程的话,就会ThreadAbortException
异常,因此这样不行。
后来找到了解决办法:
Thread.IsBackground 设置线程为后台线程。
在主线程初始化的时候,设置&Thread.CurrentThread.IsBackground
=这样,主线程就是后台线程,在关闭主程序的时候就会关闭主线程,从而关闭所有线程。
但是这样的话,就会强制关闭所有正在执行的线程,所以在关闭的时候要对线程工作的结果保存。
——————————————
MSDN对前台线程和后台线程的解释:
托管线程或者是后台线程,或者是前台线程。后台线程不会使托管执行环境处于活动状态,除此之外,后台线程与前台线程是一样的。一旦所有前台线程在托管进程(其中
.exe&是托管程序集)中被停止,将停止所有后台线程并关闭。通过设置
Thread.IsBackground 属性,可以将一个线程指定为后台线程或前台线程。例如,通过将
Thread.IsBackground 设置为 true,就可以将线程指定为后台线程。同样,通过将 IsBackground 设置为
false,就可以将线程指定为前台线程。从非托管代码进入托管执行环境的所有线程都被标记为后台线程。通过创建并启动新的 Thread
对象而生成的所有线程都是前台线程。如果要创建希望用来侦听某些活动(如套接字连接)的前台线程,则应将
Thread.IsBackground 设置为 true,以便进程可以终止。
——————————————
C#程序的几种退出方法:
1.Application.Exit();
//好像只在主线程可以起作用,而且当有线程,或是阻塞方法的情况下,很容易失灵
2.System.Environment.Exit(0);
//无论在主线程和其它线程,只要执行了这句,都可以把程序结束干净
3.this.Close();
4.Application.ExitThread();
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。C#多线程、跨线程与线程安全的示例详解-阿里云资讯网
C#多线程、跨线程与线程安全的示例详解
发布时间:
更新时间:
来源:网络
上传者:用户
C#多线程、跨线程与线程安全的示例详解(三种不同方法) &代码如下
using System.T public static class Extensions &&& { &&&&&&& //控件扩展方法(用于跨线程操作),因为为了线程的安全,防止资源竞争出现死锁或不一致的状态,.NET是不允许进行跨线程访问窗体控件的。 &&&&&&& public static void SafeCall(this Control ctrl, Action callback) &&&&&&& { &&&&&&&&&&& if (ctrl.InvokeRequired) &&&&&&&&&&& { &&&&&&&&&&&&&&& ctrl.Invoke(callback); &&&&&&&&&&& } &&&&&&&&&&& else &&&&&&&&&&& { &&&&&&&&&&&&&&& callback(); &&&&&&&&&&& } &&&&&&& } &&& } & &&& public partial class Form1 : Form &&& { &&&&&&& public Form1() &&&&&&& { &&&&&&&&&&& InitializeComponent(); &&&&&&&&&&& CheckForIllegalCrossThreadCalls =//方法二(禁用异常,不检查跨线程调用的安全问题,可以自由拖动窗体,不过在严格条件下也不可取,数据可能不一致) & &&&&&&&&&&& //方法三(推荐使用) &&&&&&&&&&& //把你要保护起来的代码作为一个回调,然后任何需要保护一些代码的地方都可以这样调用 &&&&&&&&&&& ThreadPool.QueueUserWorkItem(h =& &&&&&&&&&&& { &&&&&&&&&&&&&&& int i = 0; &&&&&&&&&&&&&&& while (true) &&&&&&&&&&&&&&& { &&&&&&&&&&&&&&&&&&& //如果没有SafeCall方法,将出现“线程间操作无效: 从不是创建控件“textBox1”的线程访问它。”的错误 & &&&&&&&&&&&&&&&&&&& ////匿名委托 &&&&&&&&&&&&&&&&&&& //textBox1.SafeCall(delegate() &&&&&&&&&&&&&&&&&&& //{ &&&&&&&&&&&&&&&&&&& //&&& textBox1.Text = (i++).ToString(); &&&&&&&&&&&&&&&&&&& //}); &&&&&&&&&&&&&&&&&&& //Lambda表达式 &&&&&&&&&&&&&&&&&&& textBox1.SafeCall(() =& &&&&&&&&&&&&&&&&&&& { &&&&&&&&&&&&&&&&&&&&&&& textBox1.Text = (i++).ToString(); &&&&&&&&&&&&&&&&&&& }); &&&&&&&&&&&&&&&&&&& //Thread.Sleep(100); &&&&&&&&&&&&&&& } &&&&&&&&&&& }); &&&&&&& } & &&&&&&& //抽奖示例 &&&&&&& public bool flag = &&&&&&& public void choujiang() &&&&&&& { &&&&&&&&&&& flag = &&&&&&&&&&& while (flag) &&&&&&&&&&& { &&&&&&&&&&&&&&& Random rnd = new Random(); &&&&&&&&&&&&&&& textBox1.Text = rnd.Next(1, 100).ToString(); &&&&&&&&&&&&&&& //Application.DoEvents();//方法一:这样也可以防止UI界面线程的阻塞,不至于被卡死。但是在拖动界面或其他操作的时候,程序会被暂停 &&&&&&&&&&& } &&&&&&& } &&&&&&& //开始 &&&&&&& private void button1_Click(object sender, EventArgs e) &&&&&&& { &&&&&&&&&&& //choujiang();//方法一 &&&&&&&&&&& new Action(choujiang).BeginInvoke(null, null);//方法二 &&&&&&& } &&&&&&& //暂停 &&&&&&& private void button2_Click(object sender, EventArgs e) &&&&&&& { &&&&&&&&&&& flag = &&&&&&& } &&& }
& 异步线程池 &代码如下
delegate double weituo(double d); &&&&&&& static weituo w = new weituo(perimeter); &&&&&&& /// &summary& &&&&&&& /// 计算周长 &&&&&&& /// &/summary& &&&&&&& /// &param name=&d&&&/param& &&&&&&& public static double perimeter(double d) &&&&&&& { &&&&&&&&&&& return d * Math.PI; &&&&&&& } &&&&&&& /// &summary& &&&&&&& /// 异步完成后回调的方法 &&&&&&& /// &/summary& &&&&&&& /// &param name=&result&&&/param& &&&&&&& public static void method(IAsyncResult result) &&&&&&& { &&&&&&&&&&& Console.Write(&hi~&); &&&&&&&&&&& Console.WriteLine(w.EndInvoke(result)); &&&&&&& }
&&&&&&& static void Main(string[] args) &&&&&&& { &&&&&&&&&&& //开始异步执行 &&&&&&&&&&& w.BeginInvoke(10, new AsyncCallback(method), null); &&&&&&&&&&& w.BeginInvoke(20, new AsyncCallback(method), null); &&&&&&&&&&& Console.Read(); &&&&&&& }
_________________________________ /// &summary& &&&&&&& /// 静态方法不需要实例化 &&&&&&& /// &/summary& &&&&&&& /// &param name=&d&&&/param& &&&&&&& public static void perimeter(object d) &&&&&&& { &&&&&&&&&&& Console.WriteLine(Math.PI * (double)d); &&&&&&&&&&& Thread.Sleep(1000); &&&&&&& } &&&&&&& static void Main(string[] args) &&&&&&& { &&&&&&&&&&& int i = 1; &&&&&&&&&&& WaitCallback wcb = new WaitCallback(perimeter); &&&&&&&&&&& while (i & 15) &&&&&&&&&&& { &&&&&&&&&&&&&&& //将任务排入队列以便执行,您的回调方法将在某个线程池线程可用时执行 &&&&&&&&&&&&&&& ThreadPool.QueueUserWorkItem(wcb, (double)i); &&&&&&&&&&&&&&& ++i; &&&&&&&&&&& } &&&&&&&&&&& Console.Read(); &&&&&&& }
优点: &使用线程可以把占据长时间的程序中的任务放到后台去处理 &用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度 &程序的运行速度可能加快 &在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。
缺点: &如果有大量的线程,会影响性能,因为操作系统需要在他们之间切换; &更多的线程需要更多的内存空间 &线程会给程序带来更多的bug,因此要小心使用 &线程的中止需要考虑其对程序运行的影响 &通常块模型数据是在多个线程间共享的,需要一个合适的锁系统替换掉数据共享
本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:zixun-group@service.aliyun.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。
在命令行模式下: % 当前完整的文件名 %:h 文件名的头部,即文件目录.例如../path/test.c就会为../path %:t 文件名的尾部.例如../path/test.c就会为test.c %:r 无扩展名的文件名.例如../path/test就会成为test %:e 扩展名 %&&& 当前文件名 %:h&&& 文件名...
最近开始捡起C语音来看,《c语言实用基础》,一边看一边做例子学习。然后发现,每次写完一个例子后,都要写几个字符,去编译并执行一下,然后就想看看能不能利用vim的map映射,把这种常规性的命令绑定到一个快捷键上去,查了一些资料后,果真是可以实现的。 先摆出来怎么用的。 打开~/.vimrc文件,并在最后以后之后粘贴上一下代码: Example &代码如下 &映射命令行下的c...
Session过期
我们知道WEB服务器的Session是与客户端浏览器线程关联的,如果用户关闭了浏览器,服务端创建的Session对象也将会失效,但是,IIS在处理Session时,默认配置下,并不回立即将用户Session失效,通常需要等待1分钟左右时间,在这1分钟期间,用户的Session信息依然存储在服务端内存,如果被非法劫持利用的话很容易造成安全问题,所以在某些特定的场合,需要用户在页面窗口/标签关闭...
c++ 的一个常见面试题是让你实现一个 String 类,限于时间,不可能要求具备 std::string 的功能,但至少要求能正确管理资源。具体来说: 了解string类 & 在我们研究string类犯了什么毛病之前,还让我先说一下如何了解一个C++的类。我们要了解一个C++的类,一般来说,要从三个方面入手。 & 一、&&&&&n...
C++语法基础
关键字const有什么含意?修饰类呢?static的作用,用于类呢?还有extern c的作用 & const意味着&只读&,下面的声明都是什么意思?&& &代码如下&&&& const int *a;&& int ...
先说Foreach和For的区别,Foreach是针对对象进行遍历的,不需要定义循环次数,但是有个缺点,Foreach遍历取的是只读数据,不能在Foreach中进行对象的增删改,而For循环就可以。你这个改成while循环的代码如下: &代码如下 int i=0;while(i&ds.Table[&userreg&].Rows.Count){i++;} 例...
若您要投稿、删除文章请联系邮箱:zixun-group@service.aliyun.com,工作人员会在5个工作日内回复。
售前咨询热线
支持与服务
资源和社区
关注阿里云
International

我要回帖

更多关于 终止当前线程的运行 的文章

 

随机推荐