while(true)Thread.Sleep(XX)我通常是⽤这种写法,有
没有更好的写法或者改进
⽐如⼀个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),但只循环两次。
{
writeline用什么替代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的同步模式,更多的时候⽤的是begin或者async的异步⽅式
while(true) sleep(x)这,是⾃创的多线程中执⾏效率的写法,
while(true) sleep(x)也是⼀种不错的写法,不过最好在循环体中加个全局退出Event的判断,便于程序退出彻底
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论