【问题】为什么 System.Timers.Timer 更改间隔时间后的第一次触发时间是设 ...

打印 上一主题 下一主题

主题 541|帖子 541|积分 1623

【问题】为什么 System.Timers.Timer 更改间隔时间后的第一次触发时间是设定时间的三倍?
独立观察员 2022 年 9 月 4 日
在编写 “Wifi 固定器 [1]” 程序时,按如下方式使用了定时器
  1. //声明;
  2. private Timer _Timer = new Timer() { Interval = 1, AutoReset = true };
  3. //设置处理方法;
  4. _Timer.Elapsed += new ElapsedEventHandler(TimerHandler);
  5. /// <summary>
  6. /// 定时器任务
  7. /// </summary>
  8. private async void TimerHandler(object source, ElapsedEventArgs e)
  9. {
  10.     if (_Timer.Interval == 1) //如果是第一次执行
  11.     {
  12.         _Timer.Interval = 1000 * Configs.CheckInterval; //设置Interval为想要的间隔时间。
  13.     }
  14.    
  15.     //刷新连接状态;
  16.     _profileRadio = GetProfileRadio(_fixedWifiPack);
  17.     if (_profileRadio.IsConnected)
  18.     {
  19.         Console.WriteLine("该 Wifi 已连接,无需操作");
  20.         return;
  21.     }
  22.     Console.WriteLine($"即将尝试连接【{_fixedWifiPack.Ssid}】...");
  23.     bool result = await NativeWifi.ConnectNetworkAsync(_fixedWifiPack.Interface.Id, _fixedWifiPack.ProfileName,
  24.         _fixedWifiPack.BssType, TimeSpan.FromSeconds(5));
  25.     Console.WriteLine($"连接结果:{(result ? "成功" : "失败")}");
  26. }
  27. //开启
  28. if (_Timer.Enabled)
  29. {
  30.     Console.WriteLine($"目前监控已处于开启状态,无需重复操作");
  31.     return;
  32. }
  33. _Timer.Start();
  34. Console.WriteLine($"【开启监控成功】检测间隔时间为 {Configs.CheckInterval}s");
  35. //关闭
  36. if (!_Timer.Enabled)
  37. {
  38.     Console.WriteLine($"目前监控已处于关闭状态,无需重复操作");
  39.     return;
  40. }
  41. _Timer.Stop();
  42. _Timer.Interval = 1;
  43. Console.WriteLine($"【关闭监控成功】{Environment.NewLine}");
复制代码
 现象:
 
也就是,Timer 的 Interval 初始以及停止时,都设置为 1,为的是启动的时候能马上触发一次。然后在第一次触发时修改 Interval 为需要的间隔时间,用作后续的触发间隔。然后问题就来了,修改间隔后的那次触发,距离启动时立马触发的那次,间隔时间达到了设定间隔时间的 3 倍,而且每次都是这样。
 
修改时间间隔的地方加上先停止后启动,问题依旧:

 
不使用异步方法,问题依旧:

 
怀疑是和线程池有关系,进而和 CPU 核心数有关,我这个是四核:

 
使用 毫秒定时器 [2] 或 多媒体定时器 [3] 也还是同样的现象。
 
看到网上也有人遇到类似但不完全相同的问题(《System.Timers.Timer 非常不准确》[4]):

 
可以看到,他是使用了并行计算所以出问题了,但是我这里并没有使用并行计算。
 
然后网上一个讨论帖(《System.Timers.Timer 为什么会失效??》[5])是这样说的:

 
因为怀疑计时不准,所以有好多人自己封装调用 winmm.dll 中的 “多媒体计时器” 来形成自定义的定时器,我尝试了两种(上面提到过),问题还是一样,所以可能他们这种不能解决我遇到的问题。
总之,问题还没解决,所以大家有什么想法或方法,还请不吝赐教。
 
附 - 参考资料及整理的资料:
1、Wifi 固定器 代码:https://gitee.com/dlgcy/DLGCY_FixedWifi/tree/Blog20220904
2、毫秒定时器(整理版代码):https://gitee.com/dlgcy/dotnetcodes/blob/dlgcy/DotNet.Utilities/%E5%AE%9A%E6%97%B6%E5%99%A8/MillisecondTimer.cs
3、多媒体定时器(原始代码托管):https://gitee.com/dlgcy/dotnetcodes/blob/dlgcy/DotNet.Utilities/%E5%AE%9A%E6%97%B6%E5%99%A8/MultimediaTimer.cs
4、《System.Timers.Timer 非常不准确》:https://qa.1r1g.com/sf/ask/2286140321/
5、《System.Timers.Timer 为什么会失效??》:https://bbs.csdn.net/topics/90487784?list=764574
6、《Timer 计时不准确的解决方案 每次都重新调整,修正误差》(提到多媒体定时器的文章):https://www.cnblogs.com/chucklu/p/4673600.html
7、《Timer 计时不准确的问题及解决方法》(提到毫秒定时器的文章):https://www.cnblogs.com/dehai/p/4347061.html
 
原创文章,转载请注明: 转载自 独立观察员
本文链接地址: 【问题】为什么 System.Timers.Timer 更改间隔时间后的第一次触发时间是设定时间的三倍?[http://dlgcy.com/why-spent-three-more-time-to-start-timer-after-modify-interval/]
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小秦哥

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表