0

我有一个现有的应用程序,其中有 1 个线程在后台运行一些密集的工作,每个numOfMinutesInterval. 这以前是使用Thread.Sleep(在整个间隔期间睡觉)完成的,但我读过 Thread.Sleep 是邪恶的,而且它的设计草率,所以我想改变一个信号机制。下面是我刚刚编写的代码(使用 wpf 中的调度程序计时器,但我认为在这个小场景中,winforms 计时器也是如此)。

调度程序(在 UI 线程中运行)每秒滴答一次,并在滴答函数内部检查是否已通过间隔,如果已通过,它将发出 manualresetevent 信号Set()。我想知道如果密集的工作超过了间隔期,这是否是糟糕的设计?如果我设置了numOfMinutesInterval = 1,但工作耗时 1 分 1 秒,这是否意味着我们将跳过 1 个调用,因为在工作仍在完成且工作线程尚未阻塞时set(),滴答声正在尝试事件。set()

另请注意,我lastWorkDoneTime = DateTime.Now;在调用之后设置了Set(),我应该将其移至工作线程(lastWorkDoneTime = DateTime.Now;之前调用manualResetEvent.WaitOne();)吗?

如果这是糟糕的设计,我应该怎么做才能改变它?谢谢阅读!

//thread work done here
private void MyDoWork_ThreadStart() 
{
  while(FlagApplicationStillRunning == true)
  {
    //do the intensive work here
    manualResetEvent.WaitOne();
  }
}


// tick every second
private int numOfMinutesInterval = 1;
private DateTime lastWorkDoneTime = DateTime.Now;
private void DispatcherTimer_Tick(object sender, EventArgs e) 
{
  if((DateTime.Now - lastWorkDoneTime).Minutes > numOfMinutesInterval)
  {
    manualResetEvent.Set();
    lastWorkDoneTime = DateTime.Now;
  }
}
4

1 回答 1

0

您可以只开始一项任务并让它执行密集的工作。

private void DispatcherTimer_Tick(object sender, EventArgs e) 
{
    if ((DateTime.Now - lastWorkDoneTime).Minutes > numOfMinutesInterval)
    {
        Task.Factory.StartNew(DoIntensiveWork());
        lastWorkDoneTime = DateTime.Now;
    }
}

至于设置,lastWorkDoneTime这取决于你。如果您将其设置为触发任务的对象,则您有可能同时运行两个或多个任务来执行该工作。如果将其设置在执行工作的函数末尾,则会引入延迟,该延迟取决于完成工作所需的时间。

我实际上会考虑使用其中一个计时器对象,并让它为您处理时间而不是使用DispatcherTimer_Tick事件。有System.Timers.TimerSystem.Threading.Timers等。

帮助确定最适合您的计时器选项: 比较 .NET Framework 类库中的计时器类

于 2013-02-21T00:42:45.777 回答