Windows服务不断运行

时间:2011-02-01 15:47:02

标签: c# windows-services

我创建了一个名为 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();
 }

ThreadWorker ProxyEventLogger.WriteEntry("Main thread entered")内,{{1}}不会被解雇。

6 个答案:

答案 0 :(得分:142)

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秒钟。您需要将其替换为您需要执行的工作 - 监控代理设置等。

最后,在Windows服务的OnStop()回调中,您希望通知线程停止运行。使用_shutdownEvent

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

希望这有帮助。

答案 1 :(得分:6)

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

修改

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

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

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

答案 2 :(得分:2)

当然不会在while方法中添加OnStart循环。这将告诉操作系统该服务尚未启动,因为它无法从OnStart方法安全退出。我通常会在Timer方法中创建一个OnStart。然后在Ticks方法中,我调用必要的方法以使应用程序运行。

或者,您可以执行以下操作:

// The main entry point for the process 
static void Main() 
{ 
    System.ServiceProcess.ServiceBase[] ServicesToRun; 
    ServicesToRun = new System.ServiceProcess.ServiceBase[] { new WinService1() }; 
    System.ServiceProcess.ServiceBase.Run(ServicesToRun); 
} 

有关Windows服务的详细信息,您可以获得一个框架示例here

答案 3 :(得分:2)

使用控制台应用演示的示例代码。希望这会有所帮助..

 class Program
{
    private static CancellationTokenSource _cancellationTokenSource;
    private static ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
    private static Thread _serviceStartThread;
    private static Thread _serviceStopThread;

    private static int workcounter = 0;
    static void Main(string[] args)
    {

        _cancellationTokenSource = new CancellationTokenSource();
        _serviceStartThread = new Thread(DoWork);
        _serviceStopThread = new Thread(ScheduledStop);
        StartService();
        StopService();
    }

    private static void StartService()
    {
        _serviceStartThread.Start();

    }

    private static void StopService()
    {
        _serviceStopThread.Start();
    }


    /// <summary>
    /// Triggers a cancellation event for stopping the service in a timely fashion.
    /// </summary>
    private static void ScheduledStop()
    {
        while (!_shutdownEvent.WaitOne(0))
        {
            if (workcounter == 10)
            {
                _cancellationTokenSource.Cancel();
            }
        }
    }

    /// <summary>
    /// Represents a long running Task with cancellation option
    /// </summary>
    private static void DoWork()
    {

        while (!_shutdownEvent.WaitOne(0))
        {
            if(!_cancellationTokenSource.Token.IsCancellationRequested)
            {
                workcounter += 1;
                Console.Write(Environment.NewLine);
                Console.Write("Running...counter: " + workcounter.ToString());
                Thread.Sleep(1000);//Not needed, just for demo..
            }
            else
            {
                Console.Write(Environment.NewLine);
                Console.Write("Recieved cancellation token,shutting down in 5 seconds.. counter: " + workcounter.ToString());
                _shutdownEvent.Set();
                Thread.Sleep(5000);//Not needed, just for demo..
            }

        }
    }
}

答案 4 :(得分:0)

为什么不在Windows服务类型的解决方案中创建新项目?这将设置您需要实现的所有结构,甚至包括服务启动/停止事件的处理程序。

答案 5 :(得分:0)

我认为,解决此问题的最简单方法是:

protected override void OnStart(string[] args)
{            
    new Task(() =>
    {
            new ProxyMonitor();                    
    }).Start();    
}