Windows服务不断运行

Rob*_*itt 53 c# windows-services

我创建了一个名为ProxyMonitor的Windows服务,我目前处于安装和卸载服务的阶段,就像我想要的那样.

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

C:\\Windows\\Vendor\\ProxyMonitor.exe /install
Run Code Online (Sandbox Code Playgroud)

非常自我解释,然后我得到services.msc并开始服务,但当我这样做时,我收到以下消息:

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

我的代码看起来像这样:

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

然后在ProxyMonitor类中我有:

public ProxyMonitor()
{
}

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

    running = true;
    while (running)
    {
        //Execution Loop
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我需要做些什么来使服务保持活跃,因为我需要监控我需要跟踪变化等的网络.


更新:1

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

     Thread = new Thread(ThreadWorker);
     Thread.Start();
 }
Run Code Online (Sandbox Code Playgroud)

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

Mat*_*vis 145

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

using System.Threading;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private Thread _thread;
Run Code Online (Sandbox Code Playgroud)

_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();
}
Run Code Online (Sandbox Code Playgroud)

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

private void WorkerThreadFunc()
{
}
Run Code Online (Sandbox Code Playgroud)

如果你没有在这个函数中放置任何东西,线程将启动然后立即关闭,所以你必须在那里放置一些逻辑,这基本上可以让你在工作时保持线程活着.这是_shutdownEvent派上用场的地方.

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

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();
     }
} 
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

  • 乐意效劳.对于它的价值,我有一些详细的SO教程,显示(1)如何在事件查看器中拥有自己的日志(http://stackoverflow.com/questions/593454/easiest-language-for-creating -a-windows-service/593803#593803)和(2)如何在不需要InstallUtil.exe的情况下安装/卸载服务(http://stackoverflow.com/questions/1195478/how-to-make-a-net- Windows的服务启动右后的安装/ 1195621#1195621). (4认同)

Mar*_*ius 6

您需要退出OnStart处理程序,以便服务控制器意识到您的服务实际已启动.为了让它按照你想要的方式工作,你可以启动一个定时器滴答的定时器,并在它滴答时进行处理.

编辑:

尝试将System.Diagnostics.Debugger.Launch()放入您的内容OnStart以查看正在发生的事情(并将断点放入ThreadWorker).我建议将其包装#if DEBUG以确保它不会被部署.

我也意识到你没有给出Thread一个名字:

 Thread myThread = new Thread(ThreadWorker);
 myThread.Start();
Run Code Online (Sandbox Code Playgroud)