解决Thread 的关闭问题和参数传递时想到的办法.
2008-06-03 12:39
211 查看
在运用多线程的时候,往往会涉及到线程的关闭,很多人指出可以使用Thread.Abort方法来关闭线程.
在这里提出一些自己的想法:
参考一下牛津字典对单词Abort的解释:
vi.
异常中断, 中途失败, 夭折, 流产, 发育不全
n.
中止计划[任务]异常中断, 中途失败, 夭折, 流产, 发育不全
有夭折的意思
参考一下Abort的MSDN解释:
当线程对自身调用 Abort 时,效果类似于引发异常;ThreadAbortException 会立刻发生,并且结果是可预知的。但是,如果一个线程对另一个线程调用 Abort,则将中断运行的任何代码。在 finally 块运行时线程可能会终止,在这种情况下,finally 块将被终止。还有一种可能就是静态构造函数被终止。在极少数情况下,这可以防止在该应用程序域中创建该类的实例。
线程不一定会立即中止,或者根本不中止。如果线程在作为中止过程的一部分被调用的 finally 块中做非常大量的计算,从而无限期延迟中止操作,则会发生这种情况。
可见对Thread进行一个Abort调用,实际上是通过引发一个异常来进行强制关闭.这样对程序来说可能存在潜在的威胁.所以实际上.
相信很多人都有Abort后线程仍然运行的经历.实际上Thread结束失败是较小的损失.另外一可能会出现一种更大的威胁:
例如:
我有一个数据库.当用户更新表1时一定会更新表2中的一个字段.
假如开发中没有使用存储过程,而是把这2个更新放到了一个线程中去执行.那么就为问题的出现埋下了隐影.
用户通过一个Text ="UpDate"的按钮开启了这个线程,这个线程开始进行费事的更新操作.然而用户对执行2个操作所需要的时间没有很好的认识.在点击了这个按钮后就选择了退出系统.
好,麻烦来了.
由于Abort是强制结束,无疑在任何时间都可以把代码Kill了.如果运气不好,在刚执行了第一个更新步骤后就把线程喀嚓了...
这个问题的严重程度实际上是比较大的,做CS 的兄弟大概都知道.而且这样的错误实际上是难以发现的.
但是一但有这样的bug, 实际上可以认为系统是健壮性不高的.
所以我提出一种使用线程并且关闭线程的其他办法.
自己对线程进行一些封装:
代码实际上很简单,无非是自己封装了一下Thread.
这样有2个好处:
(1)2003 的Thread好象是不能传递参数.将参数封装到BX_Thread中(以private object)的方式存在,可以保证Thread对他的访问.
(2) 提供了一种非 Abort的结束方式.
对于最关心的地2个问题:
可以看看WorkProc().
这里有个while循环.需要解释一下.
一般来说,多线程运用到生产消费模式的情况比较多.
最典型的:我在一个线程中将数据不断的填入一个队列.
然后开很多线程不断的重队列中取出数据进行处理.
这是,线程的执行方法通常是考虑如下的结构:
WorkProc()
{
while(true)
{
if(队列中有数据)
{
取出一个进行处理。
}
}
}
BX_Thread模型主要对这个模型的循环部分进行了修改。
WorkProc()
{
while(this.IsClosing !=true)
{
if(队列中有数据)
{
取出一个进行处理。
}
}
}
然后提供一个方法:BX_Thread.Close()
只需要将 private bool IsClosing 改为true.
线程就会自己退出循环了。
一但退出循环,线程也就自然死亡而非谋杀了。
所以这个是一种思路。BX_Thread可以这样使用:
首先改写WorkProc()满足你的需求。
BX_Thread thWorker =new BX_Thread( Parameter);
thWorker.Run(1000);
//这里的1000回导致循环一次Sleep1秒。如果Run(0)则不Sleep..
//结束
thWorker.Close();
如果不想改写WorkProc
那么可以考虑做一个接口。将线程和业务分离。
我的意思,还有一点:并不是说Abort没有存在的价值。
有时也会有Abort起来很方便的时候。
但是大多数情况,需要Thread正常结束。
而且用错了结束的方式,也会很麻烦。
BearOcean
在这里提出一些自己的想法:
参考一下牛津字典对单词Abort的解释:
vi.
异常中断, 中途失败, 夭折, 流产, 发育不全
n.
中止计划[任务]异常中断, 中途失败, 夭折, 流产, 发育不全
有夭折的意思
参考一下Abort的MSDN解释:
当线程对自身调用 Abort 时,效果类似于引发异常;ThreadAbortException 会立刻发生,并且结果是可预知的。但是,如果一个线程对另一个线程调用 Abort,则将中断运行的任何代码。在 finally 块运行时线程可能会终止,在这种情况下,finally 块将被终止。还有一种可能就是静态构造函数被终止。在极少数情况下,这可以防止在该应用程序域中创建该类的实例。
线程不一定会立即中止,或者根本不中止。如果线程在作为中止过程的一部分被调用的 finally 块中做非常大量的计算,从而无限期延迟中止操作,则会发生这种情况。
可见对Thread进行一个Abort调用,实际上是通过引发一个异常来进行强制关闭.这样对程序来说可能存在潜在的威胁.所以实际上.
相信很多人都有Abort后线程仍然运行的经历.实际上Thread结束失败是较小的损失.另外一可能会出现一种更大的威胁:
例如:
我有一个数据库.当用户更新表1时一定会更新表2中的一个字段.
假如开发中没有使用存储过程,而是把这2个更新放到了一个线程中去执行.那么就为问题的出现埋下了隐影.
用户通过一个Text ="UpDate"的按钮开启了这个线程,这个线程开始进行费事的更新操作.然而用户对执行2个操作所需要的时间没有很好的认识.在点击了这个按钮后就选择了退出系统.
好,麻烦来了.
由于Abort是强制结束,无疑在任何时间都可以把代码Kill了.如果运气不好,在刚执行了第一个更新步骤后就把线程喀嚓了...
这个问题的严重程度实际上是比较大的,做CS 的兄弟大概都知道.而且这样的错误实际上是难以发现的.
但是一但有这样的bug, 实际上可以认为系统是健壮性不高的.
所以我提出一种使用线程并且关闭线程的其他办法.
自己对线程进行一些封装:
public class BX_Thread 2 { 3 private Thread thWorker; 4 private bool IsClosing =false; 5 6 private int Interval =0; 7 private object objParameter; 8 public BX_Thread(object Parameter) 9 { 10 this.objParameter =Parameter; 11 this.thWorker =new Thread(new ThreadStart(WorkProc)); 12 this.thWorker.Priority =ThreadPriority.Lowest; 13 } 14 15 public void Run(int Interval) 16 { 17 this.thWorker.Start(); 18 } 19 20 private void WorkProc() 21 { 22 while(this.IsClosing !=true) 23 { 24 if(this.Interval !=0) 25 { 26 Thread.Sleep(this.Interval); 27 } 28 //do something 29 30 } 31 32 this.thWorker =null; 33 } 34 35 public void Close() 36 { 37 this.IsClosing =true; 38 } 39 }
代码实际上很简单,无非是自己封装了一下Thread.
这样有2个好处:
(1)2003 的Thread好象是不能传递参数.将参数封装到BX_Thread中(以private object)的方式存在,可以保证Thread对他的访问.
(2) 提供了一种非 Abort的结束方式.
对于最关心的地2个问题:
可以看看WorkProc().
这里有个while循环.需要解释一下.
一般来说,多线程运用到生产消费模式的情况比较多.
最典型的:我在一个线程中将数据不断的填入一个队列.
然后开很多线程不断的重队列中取出数据进行处理.
这是,线程的执行方法通常是考虑如下的结构:
WorkProc()
{
while(true)
{
if(队列中有数据)
{
取出一个进行处理。
}
}
}
BX_Thread模型主要对这个模型的循环部分进行了修改。
WorkProc()
{
while(this.IsClosing !=true)
{
if(队列中有数据)
{
取出一个进行处理。
}
}
}
然后提供一个方法:BX_Thread.Close()
只需要将 private bool IsClosing 改为true.
线程就会自己退出循环了。
一但退出循环,线程也就自然死亡而非谋杀了。
所以这个是一种思路。BX_Thread可以这样使用:
首先改写WorkProc()满足你的需求。
BX_Thread thWorker =new BX_Thread( Parameter);
thWorker.Run(1000);
//这里的1000回导致循环一次Sleep1秒。如果Run(0)则不Sleep..
//结束
thWorker.Close();
如果不想改写WorkProc
那么可以考虑做一个接口。将线程和业务分离。
我的意思,还有一点:并不是说Abort没有存在的价值。
有时也会有Abort起来很方便的时候。
但是大多数情况,需要Thread正常结束。
而且用错了结束的方式,也会很麻烦。
BearOcean
相关文章推荐
- 解决Thread 的关闭问题和参数传递时想到的办法.
- 启动Tomcat出现自动关闭问题的解决办法
- 浏览器兼容问题及解决办法(忽然想到的)
- 点击右键 WIN 7 资源管理器老是自动关闭或者重启问题解决办法
- Windows Live Message (MSN) 登陆错误解决办法 -- windows live communications platform 遇到问题需要关闭
- Word遇到问题需要关闭的解决办法
- 关闭UAC后边栏无法使用问题的解决办法
- 编译器&调试---emulator.exe 遇到问题需要关闭 的解决办法
- 关于Web程序打开Word、Excel后,不能关闭的问题的一个解决办法
- Android 关于“NetworkOnMainThreadException”问题的原因分析及解决办法
- MDK4.6和J-LINK调试出现问题,软件自动关闭,在网上收集整理的解决办法
- 在IE7关闭窗口,上传图片无法预览,window.status无效问题解决办法
- WORD遇到问题需要关闭解决办法
- QT中使用槽函数来关闭窗口,导致内存泄露的问题以及解决办法
- 在IE7关闭窗口,上传图片无法预览,window.status无效问题解决办法
- selenium2java如何关闭上传弹框问题的解决办法
- windows8.1 安装vs2010后 vs2010显示遇到位置问题关闭的问题解决办法
- word遇到问题需要关闭的解决办法
- 解决Thread 的关闭问题
- [转]在IE7关闭窗口,上传图片无法预览,window.status无效问题解决办法