定期运行的Windows服务

23
我正在编写一个Windows服务程序,一旦启动就会每隔X小时运行一次。完成的过程相当密集,因此我想使用后台工作进程。我使用设置文件存储运行间隔时间和服务最后运行时间。
我不确定最佳实现方式 - 我希望该服务在空闲时占用尽可能少的资源,并且在运行时需要在后台工作者中运行、报告其工作内容,然后返回到空闲模式。
我考虑过使用两个后台工作者。第一个工作者将是服务的私有本地变量,运行类似以下内容:
while (true)
{
      //create new background worker and run

      Thread.Sleep(Settings.Default.SleepTimeHours * 3600000);
}

在循环的每个迭代中创建一个子工作线程,并在完成后销毁。为了支持取消操作,我认为我必须在服务中拥有第二个工作线程的本地实例,但如果进程当前未运行,则该实例将为null。当次要工作线程完成时,它将发送我的报告,设置设置文件中的最后运行时间,然后处理工作线程并将引用设置为null。

我想知道是否有更好的方法或最佳做法。

谢谢


对于那些建议使用任务计划程序的人 - 我提出了这个选项,但架构师希望它成为一个Windows服务。 - Josh
2
@Broken Bokken:两全其美:http://www.genericgeek.com/Enable-a-service-from-command-line ;) - JustLoren
13个回答

1

我大约1小时前和同事们讨论了同样的问题!我选择了while(_isPolling)选项,因为我需要同步进行工作。我不希望其他线程(定时器方法)也执行相同的工作,并且为此实现额外的锁定似乎是浪费。


0

在查看了许多教程之后,我开发了一个Windows服务,它会每60分钟定期运行,并在后台启动进程并运行Test.exe。

public partial class Scheduler : ServiceBase
{
    private Timer timer1 = null;


    public Scheduler()
    {
        InitializeComponent();
    }
    // Get the Exe path
    private string GetPath()
    {
        Assembly assembly = Assembly.GetExecutingAssembly();
        return Path.Combine(Path.GetDirectoryName(assembly.Location), "Test.exe");

    }
    // you can right your own custom code
    // Above vista version the process works as Administrator- "runas" and in old OS it will Start process as per Administartor rights  
    public void startprocess()
    {
       // System.Diagnostics.Process.Start(GetPath());
        System.Diagnostics.Process process = null;
        System.Diagnostics.ProcessStartInfo processStartInfo;

        processStartInfo = new System.Diagnostics.ProcessStartInfo();

        processStartInfo.FileName = GetPath();

        if (System.Environment.OSVersion.Version.Major >= 6)  // Windows Vista or higher
        {
            processStartInfo.Verb = "runas";
        }
        else
        {
            // No need to prompt to run as admin
        }

        processStartInfo.Arguments = "";

        process = System.Diagnostics.Process.Start(processStartInfo);

    }
    // On start method will load when system Start 
    // timer1_tick Event will call every hour after once start the service automatically
    protected override void OnStart(string[] args)
    {
        //System.Diagnostics.Debugger.Launch();
        timer1 = new Timer();
        this.timer1.Interval = 3600000; //every 60 min
        this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Tick);
        timer1.Enabled = true;

    }

    // Timer1_tick will Start process every hour
    private void timer1_Tick(object sender, ElapsedEventArgs e)
    {
        //Write code here to do some job depends on your requirement
        startprocess();
    }
    // Method will stop the service
    // we have set the method stop service as false. so service will not stop and run every hour 
    protected override void OnStop()
    {
        timer1.Enabled = false;

    }

}


"Test.exe" 静默运行?没有控制台窗口(黑色)? - PreguntonCojoneroCabrón

-1

我应用了定时器和工作线程的组合,目前看来它运行良好。

我将定时器设置为每分钟触发一次,如果时间与计划时间匹配,我就创建我的工作线程。

我在做一些清理工作时使用了这种技术:

if (nowTimeVar.ToShortTimeString().CompareTo(houseKeep.ToShortTimeString()) == 0)
{
    myHouseKeeper = new clsHouseKeep(archiveFolder, lastday, myCounter, myLogger);                
}    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接