windows服务仍在运行但任务没有连续执行

Posted

技术标签:

【中文标题】windows服务仍在运行但任务没有连续执行【英文标题】:windows service is still running but the task is not executed continuously 【发布时间】:2021-11-16 04:35:34 【问题描述】:
 public Service1()
    
        InitializeComponent();
    

    protected override void OnStart(string[] args)
    

        try
        
            Print();
        
        catch (Exception ex)
        
            File.AppendAllText(@"C:\fold1\Log.txt", ex.ToString());
        



    
    public static void Print()
    
        //Print & Move the files after printing
        DirectoryInfo sourceinfo = new DirectoryInfo(@"C:\fold");
        DirectoryInfo target = new DirectoryInfo(@"C:\fold1");

        foreach (FileInfo fi in sourceinfo.GetFiles())
        
            if (fi.Length != 0)
            
                System.Diagnostics.Process process = new System.Diagnostics.Process();
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.Verb = "print";
                process.StartInfo.FileName = fi.FullName;
                process.StartInfo.UseShellExecute = true;
                process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                process.Start();

                if (!process.WaitForExit(10000))
                    process.Kill();
            

            MoveFile(fi.FullName);
        
    

    public static void MoveFile(string Filename)
    
        string SourcePath = @"C:\fold";
        string targetpath = @"C:\fold1";


        if (!Directory.Exists(targetpath))
        
            Directory.CreateDirectory(targetpath);
        

        string[] sourceFiles = Directory.GetFiles(SourcePath);

        foreach (string sourcefile in sourceFiles)
        
            string mfilename = Path.GetFullPath(sourcefile);
            string mname = Path.GetFileName(sourcefile);

            if (mfilename == Filename)
            
                string distnition = Path.Combine(targetpath, mname);
                File.Move(mfilename, distnition);
            
        

    
    protected override void OnStop()
     try
        
            //Move the files after printing
            DirectoryInfo sourceinfo = new DirectoryInfo(@"C:\fold");
            DirectoryInfo target = new DirectoryInfo(@"C:\fold1");

            foreach (FileInfo fi in sourceinfo.GetFiles())
            
                // File.AppendAllText(@"C:\fold1\stop.txt", "Stop method");
                MoveFile(fi.FullName);
            
         
        catch (Exception ex)
        
            File.AppendAllText(@"C:\fold1\Log.txt", ex.ToString());
        


    

我创建了一个服务,它在给定目录中静默打印文件,然后将它们移动到另一个目录,当我第一次尝试启动它时它运行良好,但它不会持续运行,我希望它打印和移动任何复制到该目录的文件,那我该怎么办? 请注意,我还是 c# 的初学者,如果你的解释太复杂,我不太明白,谢谢

【问题讨论】:

这能回答你的问题吗? Windows service stops automatically 上面链接到的文章专门解决了 OnStart 中的 try/catch,但您也应该在其他方法中使用它。任何数量的错误都可能导致服务停止/崩溃。您可能还想使用 NLog、Serilog 或 Log4NET 等日志记录框架添加一些日志记录,以便了解退出时实际发生的情况。 不,它不能回答我的问题 【参考方案1】:

问题是,您的OnStart() 方法已经完成了具体的工作并且永远 返回。但是服务管理器被设计成最多等待 60 秒,直到 OnStart() 方法返回,否则进程将被杀死。

因此,与其直接在OnStart() 方法中调用您的代码,不如实例化一个新的任务或线程来完成工作并立即退出OnStart() 方法。在OnStop() 方法中,您必须通知并行运行的代码停止(例如,通过使用CancellationToken)并等待它完成然后退出。

示例

public partial class ServiceExample : ServiceBase

    public ServiceExample()
    
        InitializeComponent();
    

    private Task Runner;
    private CancellationTokenSource Cts;

    protected override void OnStart(string[] args)
    
        if (Cts != null) // Could also simply return
            throw new InvalidOperationException("Service is already running!");

        Cts = new CancellationTokenSource();

        Runner = DoSomething(Cts.Token);
    

    private async Task DoSomething(CancellationToken cancellationToken)
    
        // Immediately return to caller to avoid "hanging" OnStart()
        await Task.Yield();

        // Regulary check if OnStop() is waiting for us
        while (!cancellationToken.IsCancellationRequested)
        
            // Call your method that should do something.
            // If it runs longer and can be intercepted,
            // forward the CancellationToken to it.
            await Worker(cancellationToken);
        
    

    protected override void OnStop()
    
        if (Cts == null) // Could also simply return
            throw new InvalidOperationException("Service already being stopped!");

        Cts.Cancel();
        Runner.Wait();
    

    private async Task Worker(CancellationToken cancellationToken)
    
        Trace.WriteLine($"DateTime.UtcNow: Do some heavy work!");
        await Task.Delay(TimeSpan.FromSeconds(1));

        if (cancellationToken.IsCancellationRequested)
            return;

        await Task.Delay(TimeSpan.FromSeconds(1));
    

【讨论】:

感谢您的友好回复@Oliver,我尝试使用您的代码,但它不起作用,也许我弄错了,我应该把我的任务放在哪里?在这种情况下,我的任务是一个名为 print() 的方法,我希望该方法不断运行,请注意,我是 C# 的初学者,所以我不太确定在这种情况下我做错了什么,谢谢 稍微更新了代码示例。您应该将Worker() 方法替换为您的方法,并使用this helper 将CancellationToken 转发到长时间运行的WaitForExit() 方法。

以上是关于windows服务仍在运行但任务没有连续执行的主要内容,如果未能解决你的问题,请参考以下文章

windows任务计划程序是怎么回事,有啥用途,该怎么设置??

关闭后,我的 Windows 窗体应用程序仍在作为任务运行

我启动windows任务管理器,发现有的程序明明没有运行,但是在进程里还是会有不少的程序?是后台吗?

win2003给一个服务制定任务计划为每一小时重启一次,怎么做

WIN7 64位系统任务计划程序里运行VBS脚本 报错,脚本本身没问题!请问怎么解决?

win7任务管理器无法显示任务 明明后台在运行 但在任务管理器应用程序任务一栏却没有显示 求解