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),但只循环两次。
        {
            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的判断,便于程序退出彻底

 

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

netyou

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值