【问题标题】:Keep a track of time and do something at a particular time跟踪时间并在特定时间做某事
【发布时间】:2011-07-08 21:26:37
【问题描述】:

工作很慢,所以我决定写一个小应用程序来打发时间。它基本上是一个应用程序,用户可以在其中设置时间和操作(关闭、注销等)。

我的问题是,我的程序跟踪时间的最佳方式是什么?我可以做的一件事是每 x 秒与 DateTime.now 进行比较,但这给了我 x 秒的误差范围。

我可以/应该创建一个秒表并让它滴答作响。当它达到0时,它会触发一个事件吗?

【问题讨论】:

标签: c# datetime


【解决方案1】:

您可以创建一个计时器,并将其间隔设置为从现在到操作应该发生的时间量。然后,在 OnTick 事件处理程序中,执行操作(并停止计时器)。

【讨论】:

    【解决方案2】:

    或者您可以使用 Windows 事件调度程序。

    【讨论】:

    • 观看有趣的 YouTube 视频,或制作有用的东西。
    【解决方案3】:

    我通常做的是将 DateTime.Now 与设置的 DateTime 进行比较,然后找到作为 TimeSpan 的差异,然后设置一个具有正确间隔的计时器。当计时器用完时,将执行正确的操作。

    如果你把它提升到一个新的水平,我做了类似的事情,它允许设置 DayOfTheWeek、时间间隔和一天中的时间。服务会找出下一个并相应地触发。

    基本上是创建我自己的计划任务windows服务。

    【讨论】:

      【解决方案4】:

      来自 WinAPI 的 CreateWaitableTimer 似乎特别适合这项任务。我发现分辨率足以满足大多数需求。

      您可以为 .NET 使用以下包装器:

      public class WaitableTimer: IDisposable
      {
          [DllImport("kernel32.dll")]
          private static extern SafeWaitHandle CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName);
      
          [DllImport("kernel32.dll", SetLastError = true)]
          [return: MarshalAs(UnmanagedType.Bool)]
          private static extern bool SetWaitableTimer(SafeWaitHandle hTimer, [In] ref long pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr lpArgToCompletionRoutine, bool fResume);
      
          [DllImport("kernel32.dll")]
          private static extern bool CancelWaitableTimer(SafeWaitHandle hTimer);
      
          private SafeWaitHandle _handle;
          private EventWaitHandle _waitHandle;
          private readonly AutoResetEvent _cancelEvent = new AutoResetEvent(false);
      
      
          public WaitableTimer()
          {
              _handle = CreateWaitableTimer(IntPtr.Zero, true, "WaitableTimer_" + Guid.NewGuid());
              _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
              _waitHandle.SafeWaitHandle = _handle;
          }
      
          public void InterruptWait()
          {
              _cancelEvent.Set();
          }
      
          public bool WaitUntil(DateTime eventTime)
          {
              long duetime = eventTime.ToFileTime();            
      
              if (SetWaitableTimer(_handle, ref duetime, 0, IntPtr.Zero, IntPtr.Zero, true))
              {
                  return WaitHandle.WaitAny(new[] { _waitHandle, _cancelEvent }) == 0;
              }
              else
              {
                  throw new Win32Exception(Marshal.GetLastWin32Error());
              }
          }
      
          public void Dispose()
          {
              InterruptWait();
              _handle.Dispose();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多