如何在不用sleep(1000)的情况下叫程序等待?

by_封爱 版主 2017-04-05 04:11:12
需求是这样的.有一个采集温度的东西 返回一个double的温度.

比如

public double GetTemp()
{
var a=....
return a;
}

然后流程就是"温度达到18度后执行什么什么..否则就一直'判稳'".

我原来的代码是这样的.比如点击开始的时候


ThreadPool.QueueUserWorkItem(state => doit());

在doit中我是这样实现的.

var temp=GetTemp();
do
{
temp=GetTemp();
Application.DoEvents();
Thread.Sleep(1000);
}while(temp>18)


其实是能实现了.

但是我看到很多帖子中 都看到有人说过 "代码里一般情况下根本不会出现sleep(1000)",,这代码根本不合理这种..

那么我问下..按照我这个需求 还有别的办法吗? 还是这个已经是最优方式?

另外
...全文
1075 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
okkk 2017-04-12
  • 打赏
  • 举报
回复
引用 26 楼 angel6709 的回复:
[quote=引用 25 楼 liuyuehui110 的回复:] [quote=引用 17 楼 bwangel 的回复:] [quote=引用 16 楼 okkk 的回复:] 使用sleep 使用timer 使用while(true) 使用信号量(resetevent,mutex等) 使用异步回调 架构上使用消息通知 等等.... 从性能上看 sleep,timer都是最差的。 while(true)可以有高性能,但会导致cpu满负荷运转,100%使用率。 其他的异步编程模式效率高,但开发难度也高。
这个和性能能扯上什么关系,是时效性吧。 [/quote] 写的很全啊 怎么使用异步回调啊 教教[/quote] 例子 void runcallback(Action callback ) { //do something if(callback !=null) { callback(); } } Action callback=delegate(){ }; runcallback(callback); [/quote] //主函数 void mainTask(){ dosomgthing(); loadresource(obj,onresourceok);//启动资源加载线程 return; } void onresourceok(object data){ dodatacheck(); dosomething(); } void loadresource(parameters,callback){ //保存参数,特别是callback //启动资源获取线程,如果资源已经加载到内存可以直接调用callback.就是说callback的执行线程不一定会切换。 //IO线程一般都会提供无阻塞函数,异步回调应该是使用无阻塞函数函数。特备是.net4.5下的 readasync方法。 // beginread也算是无阻塞。 但 beginread会分配阻塞变量,效率低,无法完全发挥硬件功能。 } 异步回调是使用多线程的环境执行单线程的逻辑,代码来说就是在启动其他函数的时候多传递一个callback就可以了。 在高性能的服务器端编程时,会大量用到这种方法。
yunqing1201 2017-04-11
  • 打赏
  • 举报
回复
我个人觉得,采用线程,用sleep 是没问题的!!!!
卧_槽 2017-04-11
  • 打赏
  • 举报
回复
1、不应该是while temp>18 再do么? 2、doit已经在一个线程里了,为什么还要用application.doevents? 你先把语法都弄清楚了,然后弄清楚下windows消息循环,ui线程,子线程。就再也不会问这样的问题了。 你的需求还是简单的,温度计本身没有事件,需要时间轮询查询温度。轮询的频率是1s。 那很明显这里需要用到的是定时器,System.Timer.TImer或者System.Threading.Timer是比较合适的。如果我没记错,这两个timer的触发事件本身是异步的。那么温度超过18度,那就执行你的doit,如果doit里有操作ui的地方,那就通过委托调用ui线程。 这才是符合逻辑的正道。Threed.sleep也不是不可以用。不用timer用死循环+sleep也是可行的。在这个场景里并无大碍。
拜一刀 2017-04-11
  • 打赏
  • 举报
回复
工控之类的sleep不是很正常吗 不sleep的话,你现有的参数不能保存起来吗 说起来waitforsingleobject怎么用来着,当年毕设做kinect就是用这个而不是循环判断,不做c++都忘没了
angel6709 2017-04-07
  • 打赏
  • 举报
回复
引用 25 楼 liuyuehui110 的回复:
[quote=引用 17 楼 bwangel 的回复:] [quote=引用 16 楼 okkk 的回复:] 使用sleep 使用timer 使用while(true) 使用信号量(resetevent,mutex等) 使用异步回调 架构上使用消息通知 等等.... 从性能上看 sleep,timer都是最差的。 while(true)可以有高性能,但会导致cpu满负荷运转,100%使用率。 其他的异步编程模式效率高,但开发难度也高。
这个和性能能扯上什么关系,是时效性吧。 [/quote] 写的很全啊 怎么使用异步回调啊 教教[/quote] 例子 void runcallback(Action callback ) { //do something if(callback !=null) { callback(); } } Action callback=delegate(){ }; runcallback(callback);
xuzuning 2017-04-06
  • 打赏
  • 举报
回复
你这个是 直到 temp>18 才结束 但是 ThreadPool.QueueUserWorkItem 是异步执行的,与后面还有代码有什么关系?
crystal_lz 2017-04-06
  • 打赏
  • 举报
回复
非专业马农表示这种写法没什么不对 的。。。。
Poopaye 2017-04-06
  • 打赏
  • 举报
回复
多说一句,个人认为在线程理使用sleep+while并没有啥不合理的地方
Poopaye 2017-04-06
  • 打赏
  • 举报
回复
//准备一个WaitHandle
EventWaitHandle w;
//检测温度
void CheckTemp(object sender, ElapsedEventArgs e) {
    if (GetTemp() > 18) {
        ((Timer)sender).Enabled = false;
        w.Set();
    }
}

//启动计时器
var t = new Timer(1000);
t.Elasped += CheckTemp;
t.Enable = true;
//然后等待
w.WaitOne();
//下面继续还有别的代码
by_封爱 版主 2017-04-06
  • 打赏
  • 举报
回复
引用 18 楼 shingoscar 的回复:
用Timer啊,而且明显是定时,不是等待啊
但是下面继续还有别的代码. 如果采用timer 那么就跑到了另外一个"事件"中去判断. 这个方法内 其实还是要等待的. 要等待一个信号 然后急需执行下面的代码..
Poopaye 2017-04-06
  • 打赏
  • 举报
回复
用Timer啊,而且明显是定时,不是等待啊
bwangel 2017-04-06
  • 打赏
  • 举报
回复
引用 16 楼 okkk 的回复:
使用sleep 使用timer 使用while(true) 使用信号量(resetevent,mutex等) 使用异步回调 架构上使用消息通知 等等.... 从性能上看 sleep,timer都是最差的。 while(true)可以有高性能,但会导致cpu满负荷运转,100%使用率。 其他的异步编程模式效率高,但开发难度也高。
这个和性能能扯上什么关系,是时效性吧。
okkk 2017-04-06
  • 打赏
  • 举报
回复
使用sleep 使用timer 使用while(true) 使用信号量(resetevent,mutex等) 使用异步回调 架构上使用消息通知 等等.... 从性能上看 sleep,timer都是最差的。 while(true)可以有高性能,但会导致cpu满负荷运转,100%使用率。 其他的异步编程模式效率高,但开发难度也高。
angel6709 2017-04-06
  • 打赏
  • 举报
回复
引用 14 楼 caozhy 的回复:
DateTime dt = DateTime.Now; while (new TimeSpan(DateTime.Now.Ticks - dt).TotalSeconds <= 1);
这不sleep啊,cpu100%
  • 打赏
  • 举报
回复
引用 17 楼 bwangel 的回复:
[quote=引用 16 楼 okkk 的回复:] 使用sleep 使用timer 使用while(true) 使用信号量(resetevent,mutex等) 使用异步回调 架构上使用消息通知 等等.... 从性能上看 sleep,timer都是最差的。 while(true)可以有高性能,但会导致cpu满负荷运转,100%使用率。 其他的异步编程模式效率高,但开发难度也高。
这个和性能能扯上什么关系,是时效性吧。 [/quote] 写的很全啊 怎么使用异步回调啊 教教
ljheee 2017-04-06
  • 打赏
  • 举报
回复
如果采用timer 那么就跑到了另外一个"事件"中去判断.
threenewbee 2017-04-05
  • 打赏
  • 举报
回复
DateTime dt = DateTime.Now; while (new TimeSpan(DateTime.Now.Ticks - dt).TotalSeconds <= 1);
wanghui0380 2017-04-05
  • 打赏
  • 举报
回复
我不纠结上面那些东西 我只想知道temp,为啥不是属性,为啥不是在属性里去控制线程停止,同时为啥有Thread.Sleep(1000); 尤其是这个Thread.Sleep(1000);干啥呢?你怕UI刷新不过来,你的逻辑就是每1秒取一次。那么还有啥纠结的。逻辑就是每1秒取1次啊,不用Thread.Sleep(1000);也得用timer 或者spin或者 CancellationToken token = cts.Token; token.WaitHandle.WaitOne(1000) 当然如果你一定不想看到这些也没问题,是RX就完全看不到这些了(虽然内部一样有,不过眼不见为就干净了) 下面是RX的写法
  var UIContext = SynchronizationContext.Current;//UI主线程
            //每分钟执行一次获取
            var source = Observable.Interval(TimeSpan.FromMilliseconds(1000)).Select(p =>
            {

                return 1; //你获取温度的代码,我这里简单写就写成1
            });
           var stop= source.Where(p => p > 6);//设置停止条件
            //获取执行结果,直到停止条件为真,同时设定工作线程为UI主线程,避免下面的操作产生跨线程调用错误
            var temps = source.TakeUntil(source).ObserveOn(UIContext).Subscribe(p =>
            {
                更新界面的代码;

            });
  • 打赏
  • 举报
回复
最后,这个 Sleep 如果是出现通讯程序中,有的小 demo 程序只用单机、本地环境、模拟1个客户端发送数据、几个字节“自己玩儿的”测试例子,那么可以写 Sleep,因为这种程序看上去简单。 而在上万客户端的服务器编程实践中,占用10个G内存,上万了死循环的子线程,那就完全没有必要了。而且这种程序显然比异步处理的程序要反而更复杂。 要知道自己玩儿的程序,跟经过了上千万用户的真实系统检验的程序,设计上肯定不同!不要认为自己玩儿的程序似乎也能实现某个功能,那么产品代码就也那么写了。实际上那样的代码继续写下去,系统稍微复杂一点,反而初始的想当然地死循环、轮询的写法不能灵活安排大量事件的复杂的触发关系,反而很快就乱了。
  • 打赏
  • 举报
回复
Application.DoEvents() 用来消息泵中的消息,立刻进行处理(而不等当前主线程中你的、还没有执行完毕的代码执行完毕)。当主线程中你的代码正在处理消息a的时候,你把后边的消息提前触发了,那么如果你调试,会发现系统消息胡乱跳来跳去,你的处理a的代码还没有执行完,跑到了处理b的代码里边、c的代码里边,最后又跑回a的代码里边。特别是假设上述混乱的代码还没结束,又执行到 Application.DoEvents(),甚至在一个过程中间接多层递归调用 Application.DoEvents,windows 消息处理循环全乱套了。 所以 Application.DoEvents 是 VB6 以前的机制,因为 VB 根本不支持多线程!在 .net 程序中则不需要。 在你的程序中(并不是在)更加不需要,因为你不是在主线程中使用 Application.DoEvents,这就更加乱了。
加载更多回复(10)

110,536

社区成员

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

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

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