c# 可以使用 多少个 Thread.IsBackground = true

qw_123 2015-08-29 11:36:22
我现在有一个程序,有UDP/TCP/USB/串口4中通信方式,并且它们4个都一个ReceiveData()函数,用来接收发来的数据,所以我设置了4个后台线程,即
一、 Thread TCPthreadReceive = new Thread(new ThreadStart(TCPReceiveData));
TCPthreadReceive.IsBackground = true;
TCPthreadReceive.Start();
private void TCPReceiveData();
二、
Thread UDPthreadReceive = new Thread(new ThreadStart(UDPReceiveData));
UDPthreadReceive.IsBackground = true;
UDPthreadReceive.Start();
private void UDPReceiveData();
三、
Thread USBthreadReceive = new Thread(new ThreadStart(USBReceiveData));
USBthreadReceive.IsBackground = true;
USBthreadReceive.Start();
private void USBReceiveData();
四、
Thread COMthreadReceive = new Thread(new ThreadStart(COMReceiveData));
COMthreadReceive.IsBackground = true;
COMthreadReceive.Start();
private void COMReceiveData();
1、请问这样写有没有什么坏处,目前我是这样写的,并且也能实现同时接收的。只是想搞明白这样开4个后台线程,或者说开更多这样的线程有没有什么影响?
2、这些都是当点击“连接设备”后才建立这个后台线程,只要点击 按钮就会新实例化一个后台线程,是不是要在 点击 “断开连接” 按钮时,把刚刚的后台线程关掉?
采用 UDPThread.Abort();这样的方法关闭,不关有没有影响,是不是只要窗体不关闭,点击连接按钮,就会一直创建这个后台线程?

...全文
649 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
qw_123 2015-08-31
  • 打赏
  • 举报
回复
引用 8 楼 xian_wwq 的回复:
1. 6楼对于单独线程控制叙述的比较全了。 2.单个线程适用于需要长期运行来处理数据的场景, 如果是大并发,短时间运行结束就适合用线程池。 3.其实多个功能整合在一起有利有弊, 利功能多样,使用面广;弊是如果单个出现问题,可能会影响到其他模块的工作。 个人建议可以考虑策略模式,通过配置项来决定处理那一类数据
请问我现在这种情况该如何改进啊, 各位大大,都没有正面回答我的问题呀
xian_wwq 2015-08-31
  • 打赏
  • 举报
回复
1. 6楼对于单独线程控制叙述的比较全了。 2.单个线程适用于需要长期运行来处理数据的场景, 如果是大并发,短时间运行结束就适合用线程池。 3.其实多个功能整合在一起有利有弊, 利功能多样,使用面广;弊是如果单个出现问题,可能会影响到其他模块的工作。 个人建议可以考虑策略模式,通过配置项来决定处理那一类数据
qw_123 2015-08-30
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
只有“有事件”时才应该占用CPU去处理,而且这些处理都尽快结束。什么“死循环、阻塞”之类的做法,是高性能并发和异步操作编程的大忌。
先感谢给我解答,但是没有回答的两个问题呀, 希望能解答下,好吗?
qw_123 2015-08-30
  • 打赏
  • 举报
回复
我这个界面是设计的4中通信方式,TCP通信是服务端,UDP是发送广播来获取远端的IP和端口号,USB是一个外部设备,串口就是普通的串口控件做的通信,这4个通信,在窗体运行后, UDP服务,也就是
Thread UDPthreadReceive = new Thread(new ThreadStart(UDPReceiveData));
UDPthreadReceive.IsBackground = true;
UDPthreadReceive.Start();
private void UDPReceiveData();
在窗体Form_loading的时候就先开启了这个UDP的接收函数,TCP通信是在点击“连接服务器”按钮后,执行,就是下面的这些语句是放在“连接服务器”button 事件中的,
Thread TCPthreadReceive = new Thread(new ThreadStart(TCPReceiveData));
TCPthreadReceive.IsBackground = true;
TCPthreadReceive.Start();
private void TCPReceiveData();

然后USB 和 串口的都是放在“打开USB”和“打开串口” bottom 事件中的,所以按照C#的运行机制,每次点击打开button就会执行
Thread USBthreadReceive = new Thread(new ThreadStart(USBReceiveData));
USBthreadReceive.IsBackground = true;
USBthreadReceive.Start();
private void USBReceiveData();

为什么要做这样的界面,就是目前的一个电路板有这4种通信,都要用到,所以才开发设计的这个窗体应用程序

所以我想问的是,想现在这4种通信方式要集中在一个窗体应用程序下, 接收函数USB ReceiveData();这样的接收函数,怎么开线程实时接收数据,目前功能确实是可以实现,暂时没有BUG,但是思考了下,每次点击button事件,就会执行new new Thread(new ThreadStart(USBReceiveData)); 怕出问题,想找个更合理的方式来处理这4种接收函数。
winnowc 2015-08-30
  • 打赏
  • 举报
回复
引用 5 楼 w260630 的回复:
请问,我这里该怎么修改呢, 望指点!
用独立线程,估计是使用了阻塞方式的读取,那就需要设置好超时时间,不能在没有数据时始终阻塞,否则就没法控制线程结束了。然后设置标识,线程的循环中判断标识来退出循环(可以使用CancellationToken构造,或者自定义volatile bool变量)。主 UI 线程需要的时候设置这些标识,以控制线程结束。再次开启线程前必须等待之前的线程退出。 或者,也可以不结束/重建线程,而是通过ManualResetEvent这种信号构造控制线程暂停工作,需要的时候再恢复。 这里就能看出异步方式读取数据的好处,不需要自己控制线程,有时候会轻松不少。如果是服务端应用,是不应该使用阻塞 I/O 的,你这个是客户端程序,所以也没什么。
winnowc 2015-08-30
  • 打赏
  • 举报
回复
如果只是4个线程还没什么,虽然不够优雅,但也算合理的使用。不过如果你不让线程结束,点击按钮就开新的那当然会有影响,先不说其它的,你的代码都不一定能支持对一种设备使用多个线程同时接收数据,何况这样也不合理。 Abort 非常危险,除非你非常了解 Abort 的时候会发生什么,否则不要用它。断开的时候应该给目标线程通知,或者说信号,让它退出循环正常结束。
qw_123 2015-08-30
  • 打赏
  • 举报
回复
引用 4 楼 github_22161131 的回复:
如果只是4个线程还没什么,虽然不够优雅,但也算合理的使用。不过如果你不让线程结束,点击按钮就开新的那当然会有影响,先不说其它的,你的代码都不一定能支持对一种设备使用多个线程同时接收数据,何况这样也不合理。 Abort 非常危险,除非你非常了解 Abort 的时候会发生什么,否则不要用它。断开的时候应该给目标线程通知,或者说信号,让它退出循环正常结束。
请问,我这里该怎么修改呢, 望指点!
  • 打赏
  • 举报
回复
只有“有事件”时才应该占用CPU去处理,而且这些处理都尽快结束。什么“死循环、阻塞”之类的做法,是高性能并发和异步操作编程的大忌。
  • 打赏
  • 举报
回复
线程应该通常在几毫秒、十几毫秒之内完毕,结束(归还给线程池)。而不是什么“死循环、阻塞”着。 一个进程中当时有多少子线程,应该根据并发任务而定,而不是什么4个或者或者40个。这应该是动态的,而不是死的。

110,534

社区成员

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

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

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