1、有这么一个需求,我需要每隔10秒钟处理一件事情,比较耗时,可能会处理两三秒。
最开始,我是使用的定时器,定时10秒处理一次。
这就出现了一个问题,定时一次运行,运行两三秒之后结束,然后只过了六七秒,又再次启动了(定时器固定间隔10秒)
这还算简单的,还有一种可能,定时处理的代码,处理不止两三秒,甚至10秒都处理不完,定时器会再次启动,这时候运行了两个一样的逻辑,这个还不能用加锁处理,不然上一次代码运行完,锁一解开马上运行下一次,太坑后来我换了个想法,用异步:async void Loop()
{
    while(true)
   {
          执行逻辑();
         Task.Delay(10*1000);
   }
}搞了个死循环。
这个倒是可以了,执行一次不管用了十秒还是二十秒,下次启动都是在休息10秒后运行
但是,我想知道,这个思路有没有问题延迟10秒的时候,会不会消耗什么资源,会不会比定时器效率低很多。。

解决方案 »

  1.   


    while(条件)
    {
       method();
       //......................
    }async void method()
    {
        await Task.Run(处理逻辑);}
    不要使用Task.Delay(10*1000);这些,浪费资源
      

  2.   

    更正下:async void method()
    {
        while(条件)
        {
            await Task.Run(处理逻辑);
        }
        
    }
      

  3.   

    await Task.Delay(10*1000); 不然他只是一个Task
      

  4.   

    我记得time里好像有个参数可以设置你哪个情况
      

  5.   

    你可以根据你的情况,去选择3种不同的timer。
    目前根据你说的,
    我感觉你适合使用单线程 
    System.Windows.Forms.Timer具体你看一下https://blog.csdn.net/hanjun0612/article/details/81357492
      

  6.   

    用线程池  ThreadPool.QueueUserWorkItem 上一个执行完再执行下一个
      

  7.   

    这个不可以用Ajax吗 jquery很容易实现吧 但我没接触过winform如果Ajax返回状态完成 则x=10 计时递归
      

  8.   

    每隔10秒钟处理一件事情,比较耗时,可能会处理两三秒
    -》定时器事件中处理异步也是一个道理,为什么要使用死循环while,不推荐。
      

  9.   

    用线程 解决呀 Timer  里面有线程的挂起
      

  10.   

    用线程 解决呀 Timer  里面有线程的挂起 
      

  11.   

    timer里面另起thread
    这样timer就不吃时间了,当然有几纳秒差别 
      

  12.   

    如果timer走的是中断,那么效率是你开线程的N倍。当然没有仔细研究过!!
      

  13.   

    BackgroundWorker组件,不是有一个运行处理完之后的事件么,在这里整个间隔10秒也可以啊
      

  14.   

    唉,每次都能把问题丢到莫名其妙的地方假设一群人上厕所,只有一个坑。 那么结果是什么,进去-----脱裤子--xxxx--穿裤子-冲水--出去--下一个人进来好了,现在穿裤子+冲水要10秒,仅此而已。所以人家 await Task.Delay(10*1000) //冲水
    retrun也好,continue也罢 //都是出去
    有问题么,正常操作了。行了,别扯啥线程,BackgroundWorker,timer,ThreadPool.QueueUserWorkItem 了,一个正常无比的操作,却不知道跑哪里去了
      

  15.   

    那个处理逻辑比较消耗性能,就是从10个安卓模拟器中获取数据,并且监控其中的异常(软件闪退、死机等情况,自动重启设备、自动重启软件等等)。
    这个不需要一直运行,我只要求间隔10秒,或者30秒处理一次,所以才做了间隔。
    你这个while,应该是会一直循环下去吧,处理完一次又会继续下一次。想知道有没有间隔运行的办法。
    我原本是使用定时器,后来就改成了Task.Delay(10*1000),又不知道这么写行不行,最近软件卡的厉害,我又找不到原因,才有点纠结。
      

  16.   

    我代码没有抄齐全,完整代码是:Task.Delay(1000).Wait();Task.Run(() => { LoopRefreshList(); });
    private void LoopRefreshList()
            {
                //不想用定时器
                while (this.btnSwitch.Text == "结束")
                {
                    _serverInfoRepository.InitData();
                    ServerInfoSerivce.RunAllScriptAssist();
                    ServerInfoSerivce.RunAllTouchSprite();
                    for (int i = 0; i <= 10; i++)
                    {
                        this.SetlbDateTime(new TimeSpan(0,0, 10 - i)); //这个是在UI上输出倒计时,下一次刷新处理列表的时间
                        Task.Delay(1000).Wait();
                        if (i == 10) { break; }
                    }
                }
            }
    为啥不能加锁,当然可以加锁,你只需要让上一次的结尾“冲水10秒”就行实现的办法我知道有几种只是不知道哪种比较合适,如果用Task.Delay(1000).Wait();来做延时10秒继续运行,这个本身没问题的话,我就放心了。
    主要是这个项目最近很卡。
    而整套逻辑中,只有这个循环里面占用的CPU较大,我就在纠结问题出在哪里。
      

  17.   


    同意,过早的考虑性能是不实在的, 比如你的东西多少人用,在同一时间段内多少人用个,在同一时间内多少人用同一个功能。 就5个人,逻辑没错,优化毫无意义。但还有一种可能,就是你就是想精进代码,想学习,想换一个思路。想探讨问题。
    我主要纠结的是定时器和Task.Delay(1000).Wait();这两种延时的机制,有没有差别。想询问哪种比较合适
    其他的异步回调之类的操作,需要延时应该也是需要用Task.Delay(1000)的,感觉应该没差别
      

  18.   

    无需纠结定时器和Task当然Task.Delay(1000).Wait(); 这个是同步阻塞,实际效果并不好。我们需要的是异步等待await Task.Delay(1000)至于定时器和task根本就无需去比较,这不是你项目的核心。也不是引发你卡的原因,别总跟XXX园学什么“一个Task引发的血案”,一个“定时器造成的惨案”-------这些玩意,如果有严谨论证有个印象就好。如果没有严谨论证,看看笑笑就是。
      

  19.   

    this.btnSwitch.Text == "结束",这类东西少用task 有CancelToken,有CancelTokenSource控制,不要用那些非线程创建的公共对象至于定时器和task,得看你是弃还是不弃(排队)。上面有人说单线程的定时器不会并行,但是他是排队。同样ThreadPool.QueueUserWorkItem依旧是排队。但是如果说你的while呢,那不是排队,而是绝对的前面走了后面补上。当然异步信号控制也一样,上面有人给你的Monitor也一样,他们也可以查询前面一个走没走,没走?本次弃掉当然这些都是限流策略,但是你问题不在这里你说cpu问题,你想停100让cpu下来。如果策略成功就好,如果策略不成功,你还是要去找cpu为啥高。做这种东西,本身不是关心什么Task,定时器问题。首先我们要搞清楚,是并行要求还是并发要求,是IO要求,还是要求。去查是什么引发的问题。然后设计策略“开源”+“节流”,去设计“闸门控制”。问题不是总和XXX园那样,无端就来个“xxx引发血案”--结论yyy就是xxx好,千万别xxx