简体   繁体   English

C#Windows服务

[英]C# Windows Service

Scenario 情境

I've created a windows service, but whenever I start it, it stops immediately. 我已经创建了Windows服务,但是无论何时启动它,它都会立即停止。 The service was concieved from a console application that used to subscribe to an event and watch processes on a server. 该服务是从控制台应用程序隐藏的,该控制台应用程序用于订阅事件并监视服务器上的进程。 If anything happened to process (ie It was killed), then the event would trigger the process to be restarted. 如果进程发生任何事情(即被杀死),则该事件将触发进程重新启动。 The reason I'm telling you this is because the original code used to look like this: 我之所以告诉您,是因为以前的原始代码如下所示:

Original Console App Code: 原始控制台应用程序代码:

    static void Main(string[] args)
    {
        StartProcess sp = new StartProcess();
        //Note the readline that means the application sits here waiting for an event!
        Console.ReadLine(); 
    }

Now that this code has been turned into a Windows Service, it is essentially EXACTLY THE SAME. 现在,此代码已被转换为Windows服务,它实际上完全相同。 However, the service does not sit there waiting, even with the readline, it just ends..... 但是,该服务不会坐在那里等待,即使带有readline,它也只是结束.....

New Windows Service Code: 新的Windows服务代码:

    protected override void OnStart(string[] args)
    {
        ProcessMonitor pm = new ProcessMonitor();
        Console.ReadLine();
    }

Thoughts 思想

Since the functionality is entirely encapsulated within this single class (It quite literally starts, sets up some events and waits) - How can I get the service to actually sit there and just wait? 由于功能完全封装在该单个类中(从字面上看,它确实已经启动,设置了一些事件并等待)-我如何才能将服务实际坐在那里并等待? It seems to be ignoring the readline. 它似乎无视阅读路线。 However this works perfectly as a console application, it is just far more convenient to have it as a service. 但是,它可以完美地用作控制台应用程序,将其作为服务要方便得多。

Typically you would want something like this. 通常,您会想要这样的东西。 As Joe mentioned in the comments you want Start to initialize and release control to another thread to make sure that you return within 30 seconds. 如Joe在评论中所述,您希望“ Start初始化并释放对另一个线程的控制权,以确保您在30秒内返回。

private readonly ProcessMonitor processMonitor = new ProcessMonitor();

protected override void OnStart(string[] args)
{
    processMonitor.Start();
}

protected override void OnStop()
{
    processMonitor.Stop();
}

In a Service there is no concept of a readline - there's no keyboard. 在服务中,没有读线的概念-没有键盘。 I wouldn't be surprised if this is throwing an exception at that call. 如果在该调用中抛出异常,我不会感到惊讶。 Have you checked your Application Log? 您检查过应用程序日志了吗?

Well... A service doesn't have a console input/output. 嗯...服务没有控制台输入/输出。 So the ReadLine won't stop it from executing. 因此,ReadLine不会阻止它执行。

What does ProcessMonitor do? ProcessMonitor做什么?

Typically, for services your code lives in a thread that monitors whether the service has been stopped or paused. 通常,对于服务,您的代码位于线程中,该线程监视服务是已停止还是已暂停。

OnStart()必须完成并成功结束才能将服务视为“已启动”

Move your Console.ReadLine(); 移动您的Console.ReadLine(); into your ProcessMonitor() constructor, and create your ProcessMonitor inside the constructor for the service. 到您的ProcessMonitor()构造函数中,并在该服务的构造函数中创建您的ProcessMonitor。 Your OnStart method can be empty. 您的OnStart方法可以为空。 Despite what people are saying the Console methods will NOT crash your service, however it is probably not best practice. 尽管有人说控制台方法不会使您的服务崩溃,但是这可能不是最佳实践。 I guess the proper way to keep a service running (after your timers are started) is to use a while loop with a Thread.Sleep(60000) inside it. 我猜想(在启动计时器之后)保持服务运行的正确方法是使用带有Thread.Sleep(60000)的while循环。

When I am writing a service I put all the functionality in a Class Library project, then I create a Console Application project to test the service functionality, and then a Windows Service project. 在编写服务时,我将所有功能都放在“类库”项目中,然后创建一个“控制台应用程序”项目来测试服务功能,然后创建一个Windows Service项目。 Both the Console Application and Windows Service project call one method in the Class Library to start the service functionality. 控制台应用程序和Windows服务项目都调用类库中的一种方法来启动服务功能。 If you use this technique you can call Console.WriteLine in the Class Library which can be viewed when running the Console Application. 如果使用此技术,则可以在类库中调用Console.WriteLine,在运行控制台应用程序时可以查看它。 PS Topshelf is overrated, writing a windows service is not that difficult. PS Topshelf被高估了,编写Windows服务并不难。

public partial class ProcessMonitor_Service : ServiceBase
{

    public ProcessMonitor_Service()
    {
        InitializeComponent();            
        ProcessMonitor pm = new ProcessMonitor();
    }

    protected override void OnStart(string[] args)
    {

    }

    protected override void OnStop()
    {

    }
}

public class ProcessMonitor
{
    public ProcessMonitor()
    {
        // start timers
        Console.ReadLine(); 
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM