如何在 C# 中使用 windows 服务创建计划的长 运行 进程

How to create a scheduled long running process using windows service in c#

我想创建一个 windows 服务来执行一些非常长且繁重的工作。代码在 OnStart 方法中,如下所示:

protected override void OnStart(string[] args)
{
    System.IO.File.WriteAllText(
        @"C:\MMS\Logs\WinServiceLogs.txt", 
        DateTime.Now + "\t MMS Service started."
    );

    this.RequestAdditionalTime(5*60*1000);           
    this.RunService();
}

this.RunService() 向 IIS 上托管的 WCF 服务库发送请求。它执行一些非常长的过程,从 1-20 分钟不等,具体取决于它必须处理的数据。我正在编写的这项服务应该安排在每天早上 运行。到目前为止,它 运行s 并且工作正常,但是当时间超过几秒或几分钟时,它会生成超时异常。这导致 windows 服务处于不稳定状态,我无法在不重新启动计算机的情况下停止或卸载它。因为,我正在尝试创建一个自动化系统,所以这是一个问题。

我确实做到了 this.RequestAdditionalTime(),但我不确定它是否在做它应该做的事情。我没有收到超时错误消息,但现在我不知道如何安排它,所以它每天 运行s。如果出现异常,那么下次就不会运行了。我找到了几篇文章和 SO,但是我遗漏了一些东西,我无法理解。

我应该创建一个线程吗?有的文章说OnStart里不能放重程序,那么重代码放哪里呢?现在,当服务启动时,它会进行大量数据处理,使 Windows 服务状态变为 "Starting",并保持很长时间,直到程序因超时而崩溃,或成功完成.我怎样才能启动服务,然后将状态设置为Running,而代码是运行做一些数据处理?

正如 Lloyd 在上面的评论中所说,您的情况可能更适合计划任务。但是,如果您真的想使用 Windows 服务,这就是您需要在服务代码中 add/update 的内容。这将使您的服务列为已启动而不是超时。您可以根据需要调整定时器长度。

private Timer processingTimer;

public YourService()
{
    InitializeComponent();
    //Initialize timer
    processingTimer = new Timer(60000); //Set to run every 60 seconds
    processingTimer.Elapsed += processingTimer_Elapsed;
    processingTimer.AutoReset = true;
    processingTimer.Enabled = true;
}
private void processingTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    //Check the time
    if (timeCheck && haventRunToday)
        //Run your code
        //You should probably still run this as a separate thread
        this.RunService();
}
protected override void OnStart(string[] args)
{
    //Start the timer
    processingTimer.Start();
}
protected override void OnStop()
{
    //Check to make sure that your code isn't still running... (if separate thread)

    //Stop the timer
    processingTimer.Stop();
}
protected override void OnPause()
{
    //Stop the timer
    processingTimer.Stop();
}
protected override void OnContinue()
{
    //Start the timer
    processingTimer.Start();
}