2010-10-08 131 views
1

有人可以让我知道如何从Windows服务(在C#中)运行长时间运行的进程吗?该过程可能需要几小时才能完成。该服务应检查数据库中是否有要执行的待执行作业。每项工作可以花费很长时间完成。如果没有挂起的作业,则应该休眠2分钟(可配置),然后重新开始。我如何使用Windows服务来做到这一点?提前致谢。如何在Windows服务中运行长时间运行的进程?

回答

1
  1. 创建一个新的“Windows服务”项目。
  2. 重写OnStart方法来创建一个线程。该线程将处理轮询和处理。
  3. 重写OnStop方法以设置标志。来自步骤2的线程监视这个标志并相应地终止它自己。
  4. 打开Service类的设计表面。在“属性”窗口的底部有一个名为“添加安装程序”的链接。点击它。
  5. 使用InstallUtil或将其放入安装程序包中来安装suervice。

我一直在写服务,所以随时问我后续问题。

+0

我其实不喜欢服务选项,因为它每隔两分钟就会一直敲击数据库,以检查是否有任何要执行的任务,并且在没有任何任务执行时浪费CPU时间。相反,我喜欢事件驱动的模型,只有当有待执行的作业时,进程才会被唤醒。我认为MSMQ是可能的,但我不熟悉它,需要了解如何使用它。谢谢回复。这个过程应该能够产生多个线程来节省执行多个挂起作业的时间。如果比平时花费的时间更长,还需要杀死该进程 – RKP 2010-10-11 10:49:12

+0

有趣的是,您应该提及MSMQ。当有工作要做时,我确实有SQL Server发送MSMQ消息。然后通过服务观看队列。一旦遇到非常罕见的情况,我将失去一条MSMQ消息,但只有在几秒钟内发送成千上万条消息时才会发生。 – 2010-10-12 18:26:04

0

没有什么特殊的技巧吧,除了你不能使用任何GUI /窗体或用户输入。根据定义,Windows服务没有用户I/O。将错误写入事件日志,你很好。

+0

我不能在服务的启动方法中放置一个永无止境的循环,否则服务将无法启动。所以我正在寻找一些机制来每隔几分钟触发一次作业处理代码。我设法使用Timer组件并设置其时间间隔,但是当流程运行时,我不得不停止计时器。我通过在启动过程之前禁用定时器并在过程完成后启用它来实现此目的。感谢您的回复。 – RKP 2010-10-11 17:11:18

+0

试试这个:System.Threading.Thread.Sleep(2 * 60 * 1000); – Jay 2010-10-12 14:07:33

0

这是一个更容易使用计划不是开发自己的应用程序的任务窗口,你应该给它一个尝试。

如果不工作,你期望的那样,作为周杰伦说话的方式,有没有招了,只记得有没有GUI。

+0

此服务需要每两分钟唤醒一次,而我的公司IT策略不允许计划任务的睡眠时间少于10分钟。所以我不得不选择Windows服务选项。使用控制台应用程序会更容易,更易于调试。感谢回复 – RKP 2010-10-11 10:39:01

3

你必须创建控制台应用程序是这样的

static void Main(string[] args) 

    { 
     bool createdNew; 
     Mutex m = new Mutex(true, "YourBatchProcessor", out createdNew); 
     if (!createdNew) 
     { 
      Console.WriteLine("YourBatchProcesso is already running!"); 
      return; 
     } 
     //your code goes here 

    } 

和Gmoliv说创建计划任务比运行,每2分钟

,或者如果你想写窗口服务然后像

您的服务代码
public class YourServrClass 
    { 

    private int numticks = 0; 
    private Timer _timer; 
    private bool _IsStarted; 
    private int Interval =2000; //ticks //2 sec. 
    #region Initializer 
    public YourServrClass() 
    { 
     InitializeComponent(); 
     _timer = new Timer(); 
     _timer.Interval = Interval; 
     _timer.Elapsed += new ElapsedEventHandler(this.Timer_Tick); 
    } 
    #endregion 

    #region Timer_Tick to process 

    private void Timer_Tick(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     numticks++; 
     if (_IsStarted) 
     { 
      _timer.Stop(); 

      //your code //ProcessYourData(); 
      _timer.Start(); 
     } 
    } 
    #endregion 
    protected override void OnStart(string[] args) 
    { 
      _IsStarted=true; 
    } 

    protected override void OnStop() 
    { 
      _IsStarted=false; 
    } 

} 
+0

感谢您的回复。我通过使用Timer组件解决了它,但是我的代码有点不同。我在“OnStart”方法中启动计时器,在“OnStop”方法中停止计时器,并在“Elapsed”事件处理程序中停止计时器,在运行进程之前禁用计时器,并在进程结束后重新启用计时器。它现在有效。 – RKP 2010-10-11 10:52:42

相关问题