程序关闭的时候在主线程中创建的线程需要手动结束吗?

ooolinux 2017-11-13 10:19:14
比如创建的线程为myThread,通常这个代码怎么写呢,写在form1_Close里吗?
...全文
994 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
mirrorspace 2017-11-17
  • 打赏
  • 举报
回复
之前做过一个支付程序.服务开了一个监听端口.服务自身是一个主线程.每个客户机请求过来时会给它开一个线程处理,但最多只开三个线程.如果同时有三个线程处理中,没有结束.那么新进来的请求就等待了.当时是这样设计的.但当时也没有想到办法,如果知道线程执行完子,于是就设了一个静态变量.放在线程方法的最后设为TRUE..至今也没别白,如此正确的结束在主线程中开起的线程.
引用 17 楼 sp1234 的回复:
“一个服务,开了三个线程”这个说法本身通常将体现了,没有了解比较好的并发多线程编程时的程序驱动设计机制,因此顶层设计就是虚幻的不落地的。 一个服务运行时,即可能一个线程都没开,也可能某个瞬间有200个线程在运行。“开了多少线程”这根本就是不定的。如果什么业务逻辑都不说但是只说“开了3个线程”这就等于是为了技术而技术了,线程概念反而是麻烦的根源。
  • 打赏
  • 举报
回复
“一个服务,开了三个线程”这个说法本身通常将体现了,没有了解比较好的并发多线程编程时的程序驱动设计机制,因此顶层设计就是虚幻的不落地的。 一个服务运行时,即可能一个线程都没开,也可能某个瞬间有200个线程在运行。“开了多少线程”这根本就是不定的。如果什么业务逻辑都不说但是只说“开了3个线程”这就等于是为了技术而技术了,线程概念反而是麻烦的根源。
  • 打赏
  • 举报
回复
引用 14 楼 mirror030 的回复:
弱问下 新开线程方法执行到最后一句是否就自动结束了呢 比如.一个服务,开了三个线程,不知道什么时候会结束,代码执行到最后一句是否就结束了?
一个线程执行的就是一个方法,因此线程通常几十毫秒、几百毫秒之后就结束了。至于说以为线程是“死循环的”,那其实是一个没有进行事件驱动设计思路问题,初学者通常认为线程就应该采用死循环的方式去不断地轮询什么东西,这是一种很不好的观念。
  • 打赏
  • 举报
回复
引用 13 楼 u010165006 的回复:
@sp1234 例子代码,倒不是说计算多久,有可能计算没完先关闭窗体了,就是这种情况,你说的 if 判断来安全退出,if 代码怎么写呢?
计算没有多久的话,根本不用管它。在窗体关闭之后,照样可以访问窗体上的控件,所以(即使需要访问控件的)子线程自然就会执行完毕而没有 bug,通常就根本不用考虑这些。 如果一定要考虑,那么你在窗体上创建一个 bool 类型的变量作为标志(比如叫做 closedFlag),然后子线程中必要的地方随时埋下判断
if(closedFlag)
    return;
这不就结束了嘛。关键一点在于,这是主动安全退出线程,不是让线程抛出异常。
ooolinux 2017-11-17
  • 打赏
  • 举报
回复
引用 23 楼 sp1234 的回复:
[quote=引用 19 楼 u010165006 的回复:] @sp1234 在窗体关闭之后,子线程照样可以访问窗体上的控件 —————— 这个是为什么?窗体关闭以后,主线程结束,子线程不是也被清理了吗?
什么叫做“主线程结束”?这是毫无道理的话。窗口就是一个存在着的对象,当它被关闭之后,它仍然是可以访问的,因为还有你的子线程中的代码在引用着窗口对象,所以 GC 无法立刻回收它。当你的线程(几百毫秒、或者是甚至是几秒钟几分钟之后)所执行的过程结束之后,窗口通常也就可以被 GC 销毁了。因此虽然看不到被关闭的窗口,但是它仍然存在,你的线程还是再访问它的内部的控件的,不会出现 bug。所以你在子线程未结束之前关闭窗口之后什么也不用做,毫无问题。 什么叫做“主线程结束”?我们说的主线程通常就是指windows系统一次次将用户操作消息传给窗口所使用的I/O线程,这其实谈不上结束,因为它本身并不是什么死循环,它不是我们的程序创建和维护的,我们只知道windows调用了我们注册的事件处理回调函数,我们怎么知道调用它的线程何时结束?所以这里的“主线程结束”的说法基本上是因为你基于“线程执行的都是死循环”的思路做出的猜测。[/quote] 有点了解了。
  • 打赏
  • 举报
回复
大牛来刷过帖子了,我就说一点我这边知道的吧。 线程中访问其他线程变量时,要做到以下两点: 1、所有访问集中放置。 2、访问前根据flag判断其他线程是否仍旧存在。 操作其他线程变量也是一样的处理原则。 否则你关闭程序的时候会有各种null错误。
mirrorspace 2017-11-17
  • 打赏
  • 举报
回复
感谢,好像又刷新了三观,进入新的迷雾之中... 这个支付服务是一个SOCKET程序,在whilet死循环中监听一个端口,当方法监听到请求后,会新建一个线程执行业务逻辑.在新建前会判断那个全局变量,如果是3(说明已经开了3个线程),就直接返回不受处理.否则才新开线程处理请求.... 看到你的描述后,感觉到这个监听程序新开线程时并不受自己程序的控制,而是来一个请求就会自动开线程....又迷乱了...点解?
引用 21 楼 sp1234 的回复:
[quote=引用 18 楼 mirror030 的回复:] 之前做过一个支付程序.服务开了一个监听端口.服务自身是一个主线程.每个客户机请求过来时会给它开一个线程处理,但最多只开三个线程.如果同时有三个线程处理中,没有结束.那么新进来的请求就等待了.当时是这样设计的.但当时也没有想到办法,如果知道线程执行完子,于是就设了一个静态变量.放在线程方法的最后设为TRUE..至今也没别白,如此正确的结束在主线程中开起的线程.
服务器监听客户端的请求,在没有请求到来时,应该一个线程也不会启动。当有10个并请求就会有十个I.O线程(它可能一瞬间,将处理交给Worker线程处理)。每一个线程处理时间从几毫秒到几百毫秒不等,可能瞬间有1个线程、或者10个线程,都有可能。完全可以处理几万客户端。 服务器应该是异步处理的,事件驱动方式的设计。如果把服务理解为几个(3个?)线程在那里死循环轮流处理,这是一种比较老的、现在来说比较错误的做法。[/quote]
mirrorspace 2017-11-17
  • 打赏
  • 举报
回复
这个问题我也想搞清楚.新开线程后,线程方法执行完最后一句时,这个线程到底会怎么样.也许这要用到操作系统的知识才可能解答
引用 20 楼 u010165006 的回复:
@mirror030 是不是线程代码执行完毕,线程就自动结束了? 如果myThread执行结束,是IsAlive变了,还是myThread变为null了?
  • 打赏
  • 举报
回复
引用 19 楼 u010165006 的回复:
@sp1234 在窗体关闭之后,子线程照样可以访问窗体上的控件 —————— 这个是为什么?窗体关闭以后,主线程结束,子线程不是也被清理了吗?
什么叫做“主线程结束”?这是毫无道理的话。窗口就是一个存在着的对象,当它被关闭之后,它仍然是可以访问的,因为还有你的子线程中的代码在引用着窗口对象,所以 GC 无法立刻回收它。当你的线程(几百毫秒、或者是甚至是几秒钟几分钟之后)所执行的过程结束之后,窗口通常也就可以被 GC 销毁了。因此虽然看不到被关闭的窗口,但是它仍然存在,你的线程还是再访问它的内部的控件的,不会出现 bug。所以你在子线程未结束之前关闭窗口之后什么也不用做,毫无问题。 什么叫做“主线程结束”?我们说的主线程通常就是指windows系统一次次将用户操作消息传给窗口所使用的I/O线程,这其实谈不上结束,因为它本身并不是什么死循环,它不是我们的程序创建和维护的,我们只知道windows调用了我们注册的事件处理回调函数,我们怎么知道调用它的线程何时结束?所以这里的“主线程结束”的说法基本上是因为你基于“线程执行的都是死循环”的思路做出的猜测。
  • 打赏
  • 举报
回复
一对堆纠结的东西、什么“一个静态变量”之类的,其实都是多余的。轮询阻塞式的所谓“线程程序”设计不但冗长、而且混乱。如果你从设计上先理解了异步、事件驱动设计模式,那么代码非常精简,根本不回去把多于60%的精力去空耗在什么理论“控制”上。
  • 打赏
  • 举报
回复
引用 18 楼 mirror030 的回复:
之前做过一个支付程序.服务开了一个监听端口.服务自身是一个主线程.每个客户机请求过来时会给它开一个线程处理,但最多只开三个线程.如果同时有三个线程处理中,没有结束.那么新进来的请求就等待了.当时是这样设计的.但当时也没有想到办法,如果知道线程执行完子,于是就设了一个静态变量.放在线程方法的最后设为TRUE..至今也没别白,如此正确的结束在主线程中开起的线程.
服务器监听客户端的请求,在没有请求到来时,应该一个线程也不会启动。当有10个并请求就会有十个I.O线程(它可能一瞬间,将处理交给Worker线程处理)。每一个线程处理时间从几毫秒到几百毫秒不等,可能瞬间有1个线程、或者10个线程,都有可能。完全可以处理几万客户端。 服务器应该是异步处理的,事件驱动方式的设计。如果把服务理解为几个(3个?)线程在那里死循环轮流处理,这是一种比较老的、现在来说比较错误的做法。
ooolinux 2017-11-17
  • 打赏
  • 举报
回复
@mirror030 是不是线程代码执行完毕,线程就自动结束了? 如果myThread执行结束,是IsAlive变了,还是myThread变为null了?
ooolinux 2017-11-17
  • 打赏
  • 举报
回复
@sp1234 在窗体关闭之后,子线程照样可以访问窗体上的控件 —————— 这个是为什么?窗体关闭以后,主线程结束,子线程不是也被清理了吗?
帅猪儿 2017-11-16
  • 打赏
  • 举报
回复
如果确实怕关闭不了,可以试试 (1)Application.Exit()//好像只在主线程可以起作用,而且当有线程,或者是阻塞方法的情况下,很容易失灵。 (2) System.Environment.Exit(0) //无论在主线程或其它线程,都可以把程序结束干净 (3)Application.ExitThread();
xian_wwq 2017-11-16
  • 打赏
  • 举报
回复
直接Abort,记得加上try...catch
mirrorspace 2017-11-16
  • 打赏
  • 举报
回复
弱问下 新开线程方法执行到最后一句是否就自动结束了呢 比如.一个服务,开了三个线程,不知道什么时候会结束,代码执行到最后一句是否就结束了?
ooolinux 2017-11-16
  • 打赏
  • 举报
回复
@sp1234 例子代码,倒不是说计算多久,有可能计算没完先关闭窗体了,就是这种情况,你说的 if 判断来安全退出,if 代码怎么写呢?
  • 打赏
  • 举报
回复
引用 6 楼 u010165006 的回复:
@duanzi_peng @summergo123321 @hanjun0612 @xian_wwq @stevenjin 谢谢大家,有点明白了,那如果关闭程序的时候,创建的myThread 线程可能没有计算完毕,怎么写代码手动结束它呢,写在哪个窗体事件里比较合适呢? 有讲到多线程章节的书,有没有一本书的例子跟窗体有关的,比较完善的,推荐一下有吗?
计算多久?总不能是死循环吧?如果不是死循环,那么你在这个冗长拖沓的所谓“线程”中主动埋下几个 if 判断点,不就能及时且优雅、安全地退出了嘛!
ooolinux 2017-11-16
  • 打赏
  • 举报
回复
@xian_wwq @alexshyong 好,谢谢。
正怒月神 2017-11-13
  • 打赏
  • 举报
回复
楼主先了解 前台线程和后台线程的区别。就能解决了
加载更多回复(7)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧