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