C# Windows服务将持续运行

C# Windows服务将持续运行,c#,windows-services,C#,Windows Services,我已经创建了一个名为ProxyMonitor的Windows服务,目前我正处于安装和卸载该服务的阶段,这是我想要的方式 因此,我按如下方式执行应用程序: C:\\Windows\\Vendor\\ProxyMonitor.exe /install 非常简单,然后我进入了services.msc并启动了服务,但当我这样做时,我得到了以下消息: 本地计算机上的代理监视器服务已启动,然后停止。如果没有工作要做,某些服务会自动停止,例如,性能日志和警报服务 我的代码如下所示: public stati

我已经创建了一个名为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(“输入主线程”)
它不会被触发。

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

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

编辑:

尝试将System.Diagnostics.Debugger.Launch()放在
OnStart
中以查看发生了什么(并在
ThreadWorker
中放置断点)。我建议将它包装在
#if DEBUG
中,以确保它不会被部署

我还意识到你没有给你的
线程起名字:

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

当然不会在
OnStart
方法中添加
while
循环。这将告诉操作系统服务尚未启动,因为它无法从
OnStart
方法安全退出。我通常创建一个
计时器
,该计时器在
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服务的详细信息,您可以获得一个框架示例。

需要及时返回
OnStart()
回调,因此您需要启动一个线程,在该线程中执行所有工作。我建议在类中添加以下字段:

using System.Threading;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private Thread _thread;
\u thread
字段将包含对在
OnStart()
回调中创建的
System.Threading.thread
对象的引用。
\u shutdownEvent
字段包含一个系统级事件构造,该构造将用于通知线程在服务关闭时停止运行

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

protected override void OnStart(string[] args)
{
     _thread = new Thread(WorkerThreadFunc);
     _thread.Name = "My Worker Thread";
     _thread.IsBackground = true;
     _thread.Start();
}
您需要一个名为
WorkerThreadFunc
的函数才能工作。它必须与代理签名相匹配

private void WorkerThreadFunc()
{
}
如果您没有在这个函数中放入任何内容,线程将启动,然后立即关闭,因此您必须在其中放入一些逻辑,以便在您执行工作时基本上保持线程的活动状态。这就是
\u 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()
回调中,您希望向线程发出停止运行的信号。这很容易使用
\u shutdownEvent

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

希望这有帮助。

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

 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..
            }

        }
    }
}
类程序
{
私有静态CancellationTokenSource\u CancellationTokenSource;
专用静态手动复位事件_shutdownEvent=新手动复位事件(假);
私有静态线程_serviceStartThread;
私有静态线程_serviceStopThread;
私有静态int工作计数器=0;
静态void Main(字符串[]参数)
{
_cancellationTokenSource=新的cancellationTokenSource();
_serviceStartThread=新线程(DoWork);
_serviceStopThread=新线程(ScheduledStop);
StartService();
停止服务();
}
私有静态void StartService()
{
_serviceStartThread.Start();
}
私有静态void StopService()
{
_serviceStopThread.Start();
}
/// 
///触发取消事件以及时停止服务。
/// 
私有静态void ScheduledStop()
{
while(!\u shutdownEvent.WaitOne(0))
{
如果(工作计数器==10)
{
_cancellationTokenSource.Cancel();
}
}
}
/// 
///表示具有取消选项的长时间运行的任务
/// 
私有静态void DoWork()
{
while(!\u shutdownEvent.WaitOne(0))
{
如果(!\u cancellationTokenSource.Token.IsCancellationRequested)
{
工作计数器+=1;
Console.Write(Environment.NewLine);
Write(“Running…counter:+workcounter.ToString());
Thread.Sleep(1000);//不需要,只是为了演示。。
}
其他的
{
Console.Write(Environment.NewLine);
Write(“接收到取消令牌,5秒后关闭..计数器:”+workcounter.ToString());
_shutdownEvent.Set();
Thread.Sleep(5000);//不需要,只是为了演示。。
}
protected override void OnStart(string[] args)
{            
    new Task(() =>
    {
            new ProxyMonitor();                    
    }).Start();    
}