一尘不染

Windows Service持续运行

c#

我已经创建了一个称为 ProxyMonitor 的Windows服务,目前正处于该服务的安装和卸载阶段。

所以我像这样执行应用程序:

C:\\Windows\\Vendor\\ProxyMonitor.exe /install

自我解释,然后进入services.msc并启动该服务,但是当我这样做时,我收到以下消息:

本地计算机上的代理监视器服务启动,然后停止。如果没有任何工作,某些服务会自动停止,例如,性能日志和警报服务

我的代码如下所示:

public static Main(string[] Args)
{
    if (System.Environment.UserInteractive)
    {
        /*
            * Here I have my install logic
        */
    }
    else
    {
        ServiceBase.Run(new ProxyMonitor());
    }
}

然后在ProxyMonitor类中,我有:

public ProxyMonitor()
{
}

protected override void OnStart(string[] args)
{
    base.OnStart(args);
    ProxyEventLog.WriteEntry("ProxyMonitor Started");

    running = true;
    while (running)
    {
        //Execution Loop
    }
}

onStop()我只是改变running变量false;

我需要做些什么来使该服务保持持续活动,因为我需要监视网络,跟踪更改等。


更新:1

protected override void OnStart(string[] args)
{
     base.OnStart(args);
     ProxyEventLog.WriteEntry("ProxyMonitor Started");

     Thread = new Thread(ThreadWorker);
     Thread.Start();
 }

ThreadWorkerProxyEventLogger.WriteEntry("Main thread entered")没有被解雇的范围内。


阅读 322

收藏
2020-05-19

共1个答案

一尘不染

OnStart()回调需要及时归还,所以你要揭开序幕,所有的工作都将执行一个线程。我建议向您的班级添加以下字段:

using System.Threading;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private Thread _thread;

_thread字段将包含对System.Threading.Thread您在OnStart()回调中创建的对象的引用。该_shutdownEvent字段包含系统级事件构造,该构造将用于向线程发出信号,以在服务关闭时停止运行。

OnStart()回调中,创建并启动线程。

protected override void OnStart(string[] args)
{
     _thread = new Thread(WorkerThreadFunc);
     _thread.Name = "My Worker Thread";
     _thread.IsBackground = true;
     _thread.Start();
}

您需要一个命名函数WorkerThreadFunc才能使其正常工作。它必须匹配System.Threading.ThreadStart委托人签名。

private void WorkerThreadFunc()
{
}

如果您在此函数中未添加任何内容,线程将启动,然后立即关闭,因此您必须在其中放置一些逻辑,这些逻辑基本上可以在工作时使线程保持活动状态。这是_shutdownEvent派上用场的地方。

private void WorkerThreadFunc()
{
    while (!_shutdownEvent.WaitOne(0)) {
        // Replace the Sleep() call with the work you need to do
        Thread.Sleep(1000);
    }
}

while循环检查,ManualResetEvent以查看是否已“设置”。由于我们使用初始化了对象false,因此此检查返回false。在循环内部,我们睡眠1秒钟。您需要将其替换为所需的工作-
监视代理设置等。

最后,在OnStop()Windows服务的回调中,您要向线程发出停止运行的信号。使用,这很容易_shutdownEvent

protected override void OnStop()
{
     _shutdownEvent.Set();
     if (!_thread.Join(3000)) { // give the thread 3 seconds to stop
         _thread.Abort();
     }
}

希望这可以帮助。

2020-05-19