周期性处理中线程膨胀的问题

本文关键字:问题 膨胀 线程 处理 周期性 | 更新日期: 2023-09-27 18:18:10

我想在工作线程上做一些周期性的工作,当工作完成时发出信号。当有信号时,我想等待5秒钟,然后重新开始工作。我写了下面的代码:

public class WinService : ServiceBase
{
    private readonly ManualResetEvent stopPeriodicProcess = new ManualResetEvent(false);
    protected override void OnStart(string[] args)
    {
        stopPeriodicProcess.Reset();
        ThreadPool.RegisterWaitForSingleObject(stopPeriodicProcess, InitializeEngines, null,5000, true);          
    }
    public void InitializeEngines(object state, bool timedOut)
    {       
        engine.LoadSettings();
        Task.Factory.StartNew(engine.DoSomeWork); //Fire and forget     
    }
    private void WorkCompletedEventHandler(object sender, WorkCompletedEventArgs e)
    {
        ThreadPool.RegisterWaitForSingleObject(stopPeriodicProcess,
                                               (state, timedOut) => DoPeriodicProcess(state, timedOut, e.EngineId), null,
                                               5000, true);
    }
    public void DoPeriodicProcess(object state, bool timedOut, string engineId)
    {
        if (timedOut)
        {                
            Task.Factory.StartNew(engine.DoSomeWork); //Fire and forget
        }
    }
}

public class Engine
{
    public event EventHandler<WorkCompletedEventArgs> WorkCompleted;    
    public void DoSomeWork()
    {
        //Doing some work..
        //Raise an event to signal that the work has been completed
        var args = new WorkCompletedEventArgs {EngineId = Settings.EngineId};
        RaiseWorkCompletedEvent(args);
    }
    protected virtual void RaiseWorkCompletedEvent(WorkCompletedEventArgs e)
    {
        EventHandler<WorkCompletedEventArgs> handler = WorkCompleted;
        if (handler != null)
        {
            handler(this, e);
        }
    }   
}

当我运行代码时,CPU使用率在几秒钟后显示为100%。在VS调试后,我看到太多的活的工作线程等待在RegisterWaitForSingleObjectWorkCompletedEventHandler

为什么调用RegisterWaitForSingleObject后线程没有死亡?我错过什么了吗?

周期性处理中线程膨胀的问题

未测试,但我认为这是由于事件未被重置:

private void WorkCompletedEventHandler(object sender, WorkCompletedEventArgs e)
{
    stopPeriodicProcess.Reset();
    ThreadPool.RegisterWaitForSingleObject(stopPeriodicProcess,
                                           (state, timedOut) => DoPeriodicProcess(state, timedOut, e.EngineId), null,
                                           5000, true);
}

而且我不明白你为什么要这样做,你不能使用定时器,这是专门为这种用例设计的吗?