由于多个线程运行,定时Windows服务崩溃

时间:2010-07-02 15:19:39

标签: c# multithreading windows-services timer

我正在开发一个简单的Web服务,它将数据从某些数据存储导出到数据库中。

该服务每20秒运行一次(测试间隔)。

间隔时间是通过System.Timers.Timer类实现的。

目前正在发生的事情是:

  1. 服务开始
  2. 计时器启动
  3. 20秒后,服务开始导出
  4. 导出未在接下来的20秒内完成,另一个线程开始尝试执行相同的导出。
  5. 最终服务崩溃。
  6. 我打算将导出包装到一个单独的线程中,但不确定这是否能完全解决问题。

    增加时间间隔不是一种选择,因为我不确定未来的出口量会有多大。

    欢迎任何建议。

    谢谢

    修改

    我猜我所追求的是: 1.启动计时器 2.启动线程 3.开始导出 4.在上一个线程完成之前,不要让计时器启动另一个线程......

3 个答案:

答案 0 :(得分:4)

在第3步中,您首先禁用计时器,然后在完成导出后重新启用计时器?

答案 1 :(得分:3)

我会做这样的事情。

public class MyServiceController
{
  private Thread m_Thread = new Thread(() => { Run(); });
  private ManualResetEvent m_StopSignal = new ManualResetEvent();

  public void Start()
  {
    m_Thread.Start();
  }

  public void Stop()
  {
    m_StopSignal.Set(); // Give it chance to end on its own.
    if (!m_Thread.Join(TimeSpan.FromSeconds(30))
    {
      // Tear everything down forcefully as an absolute last resort.
      m_Thread.Abort();
    }
  }

  private void Run()
  {
    while (!m_StopSignal(TimeSpan.FromSeconds(20))
    {
      // Put your code here.
    }
  }
}

这种方法为处理分配了一个专用线程,使所有内容保持同步。请注意,它使用WaitHandle来限制间隔。同样重要的是要注意我遗漏了许多代码,这些代码会使MyServiceController更强大,就像处理想要多次调用Start的调用者一样,确保工作线程结束不想和平等等。

答案 2 :(得分:1)

有时您不想停止计时器,因为它可能会产生多个线程。在这种情况下,您将每个线程的关键部分包装在Monitor.TryEnter块中,锁定共享对象,这样如果一个线程在计时器再次触发时仍在运行,则新线程将无害地崩溃。

private static object lockObject = new object();
public void DoSomething()
{
    if (System.Threading.Monitor.TryEnter(lockObject))
    {
        try
        {
            // critical stuff 
        }
        finally
        {
            System.Threading.Monitor.Exit(lockObject);
        }
    }
}