我创建了一个名为 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}}不会被解雇。
答案 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();
}