比如一个TCP通讯 里面有一个看门狗来监听连接是否正常 我通常是用这种写法,有没有更好的写法或者改进,欢迎讨论。
没什么问题,只要不是死循环或者耗费掉过多内存
看什么场合,写小程序这么写没毛病啊。
我记得有个笑话,说的是一个小白写了一个程序
printf("hello world")
然后一个老菜鸟看了,说你这个硬编码,不好,应该用一个变量
另一个老菜鸟看了,说要函数复用,应该写一个函数,提取这个变量作为参数
再一个老菜鸟看了,说要面向对象
再一个说,要设计模式,将输出和字符串类型分离
再一个说,要考虑线程安全
再一个说,...
最后为了写一个大家都认为没有毛病的hello world,程序写了1万行。
最后又来了一个菜鸟,看了这代码,大家都觉得他挑不出毛病了,结果他说了一句,这程序是干嘛滴。
不是有异步吗..
BeginReceive ....
这种写法没毛病啊,逻辑清晰易懂,写法也简洁,何来深恶痛觉之说?
分应用场景。while(true) Thread.Sleep(XX);可能要占用一个线程,也要占用一个线程的堆栈(默认1兆)。
如果是桌面应用,一般没有问题。
如果是高性能服务器,可能就要斤斤计较。如果每个连接占用一个线程,一千个连接单单线程的堆栈分配就用了一个G。还不要说线程上下文转换的开销。
高性能服务器,一般不会用while循环,而是会利用操作系统的功能(比如IOCP),以便来支持比如三万个并发连接。
从理解上,await的确会比原有的Thread晦涩,不太好理解,
可以尝试用ILSpy反编译看看源码,await用了一个AsyncStateMachine来完成异步处理,跟你自己写的源码顺序完全不同。
只要你 能正确认识自己的代码在干吗,确认能正确的达到你的目的,不会存在什么隐藏的缺陷,
就可以了,纠结于什么写法好,什么写法不好,没有任何意义。
之所以很多人不推荐Thread的写法,是因为它会占着茅坑不xx,会影响你的服务的吞吐量,
如果只是使用了1,2个线程做一些心跳、后台数据处理之类的,不会有什么问题。
总会有用到的地方。
但是也不能说他一定是对的。
class Program
{
static void Main(string[] args)
{
测试(ThreadSleep); // 我的机器输出- 工作线程数:15 IOCPS:0
Console.WriteLine("Enter继续"); Console.ReadLine();
测试(AwaitAsync); // 我的机器输出- 工作线程数:0 IOCPS:0
Console.WriteLine("Enter退出"); Console.ReadLine();
}
static void ThreadSleep()
{
for (int i = 0; i < 2; i++) // 模拟while(true),但只循环两次。
{
Thread.Sleep(2000); // Thread.Sleep会阻塞,将占用一个线程
}
}
static async void AwaitAsync()
{
for (int i = 0; i < 2; i++) // 模拟while(true),但只循环两次。
{
await Task.Delay(2000); // Task.Delay利用System的计时回调,等待时不占用线程
}
}
static void 测试(Action action)
{
var tasks = Enumerable.Range(0, 20).Select(x => Task.Run(action)).ToArray();
Thread.Sleep(3000);
显示线程数();
Task.WaitAll(tasks);
}
static void 显示线程数()
{
ThreadPool.GetMaxThreads(out var maxWorkers, out var maxIocps);
ThreadPool.GetAvailableThreads(out var workers, out var iocps);
Console.WriteLine($"工作线程数:{maxWorkers - workers} IOCPS:{maxIocps - iocps}");
}
}
这个就得请大神现身说法了。 有用Thread.Sleep 也有用 await
但是最清晰明了 一看就懂的代码 就是 while(true) Thread.Sleep(XX)
长轮询 不也是用的 Thread.Sleep(XX) 来停止 返回客户端时间。 连接拉到最大值
并不反对,我们只是反对。那些逻辑不清,根本就搞不明白自己在干嘛的写法
同步,异步,并行,并发你搞明白了么
没有搞明白,然后不知道怎么写就一概写个where(true), lock ,sleep??
所以我们不反对,只是反对根本就不知道自己在做什么的
比如,人家原本就写了个异步,然后你在写个where(ture) sleep 去等待这个异步结束。
好吧,你明白了么?该不该批,自己说
在比如我见过N年的所谓“10年的高程”,程序里遍地是lock
然后,我仔细观察了一下,他的写法(通过svn版本追溯和bug提交记录),发现但凡他搞不明白的bug,一律lock。
so,他明白了么?该不该批,自己说
sleep,为什么不利用这个睡觉的时间去做点什么?
人家客户的计算机也是真金白银换的,请你开发系统,是为了解决工作中的实际问题的,而不是替他空耗真金白银的
对于Windows,sleep醒后,要重新竞争CPU的我写运动控制卡程序时, 调试步骤,我就是用的While true 。 比如让丝杆从p1点运动到p2点, 丝杆到p2点后其伺服会反馈一个信号,我 就是用while 判断这个信号, 来判断丝杆是否运动到了p2点, 不然的话就要靠人超长等待了,反正时间一长,它肯定会走到位的。
但自动模式下我还是不敢这么用,自动模式下我是用timer+swich+if 来判断。
不是说所有这些写法都不行
假如只是写段代码让每1秒钟刷新下界面数据,那没什么问题的
如果对实时性,并发数,响应速度要求比较高,或者是CPU负载比较重的计算类程序
那更好的写法多的是
while(true){
Thread.yid();
if(xxx)
break;
}
这样呢,等待的时候把cpu占用让出去,不使用sleep
分应用场景,上位机就必须要的,时刻去监控PLC状态
while(true) sleep(x)这样的写法,是自创的多线程中执行效率最高的写法,
如果换c,最执行效率最高的写法是for(,,) sleep
另外如果在x86(64)这类平台这么干没啥问题,如果是在其他平台,执行线程可能会因为引发这个线程的线程被系统干掉,Windows下可以放心使用,其他平台需要保证这个线程不被干掉
不太好评论,什么样的用法是适应什么样的应用逻辑,也不能一概而论这种写法好与坏
但就socket而言,如果我想实现c和s的枚举传输,我有时候也会用while,但在监听方面,我一般不用while的同步www.9iBee.com模式,更多的时候用的是begin或者async的异步方式
while(true) sleep(x)这,是自创的多线程中执行效率的写法,
while(true) sleep(x)也是一种不错的写法,不过最好在循环体中加个全局退出Event的判断,便于程序退出彻底