如何使用信号机制与C#中的线程和手动资源执行密集的工作(不重叠)

本文关键字:执行 资源 工作 重叠 机制 信号机 信号 何使用 线程 | 更新日期: 2023-09-27 18:00:23

我有一个现有的应用程序,每个numOfMinutesInterval有一个线程在后台运行一些密集的工作。这之前是使用Thread.Sleep(在整个间隔期内睡眠)完成的,但我已经阅读了该线程。睡眠是邪恶的,它是草率的设计,所以我想换一种信号机制。下面是我刚刚编写的代码(使用wpf中的dispatcher定时器,但我认为在这个小场景中,winforms定时器也是如此)。

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

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

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

//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;
  }
}

如何使用信号机制与C#中的线程和手动资源执行密集的工作(不重叠)

您可以启动一项任务,让它执行密集的工作。

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框架类库