我有一个现有的应用程序,每个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;
}
}
您可以启动一项任务,让它执行密集的工作。
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.Timer
、System.Threading.Timers
等。
为了帮助确定哪种计时器选项最适合您:比较中的计时器类。NET框架类库