gpt4 book ai didi

c# - 运行 Windows 服务以观察服务运行增长内存(泄漏)

转载 作者:可可西里 更新时间:2023-11-01 12:08:06 24 4
gpt4 key购买 nike

我已经检查了这里的所有帖子,但到目前为止找不到适合我的解决方案。我确实设置了一个小服务,它应该只监视我要监视的其他服务是否运行,如果没有运行,则重新启动它并在应用程序事件日志中放置一条消息。

该服务本身运行良好,没什么特别的 :),但是当我启动该服务时,它使用大约 1.6MB 的 RAM,并且每 10 秒它增长 60-70k,这足以忍受它。我尝试处理并清除所有资源。尝试使用 System.Timers 而不是实际的解决方案,但没有任何效果如我所愿,内存仍在增长。

调试或发布版本没有区别,我在 .Net 2 上使用它,不知道它对你 3、3.5 或 4 是否有影响。

有什么提示吗?!

using System;
using System.IO;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using System.Timers;

namespace Watchguard
{
class WindowsService : ServiceBase
{

Thread mWorker;
AutoResetEvent mStop = new AutoResetEvent(false);

/// <summary>
/// Public Constructor for WindowsService.
/// - Put all of your Initialization code here.
/// </summary>
public WindowsService()
{
this.ServiceName = "Informer Watchguard";
this.EventLog.Source = "Informer Watchguard";
this.EventLog.Log = "Application";

// These Flags set whether or not to handle that specific
// type of event. Set to true if you need it, false otherwise.
this.CanHandlePowerEvent = false;
this.CanHandleSessionChangeEvent = false;
this.CanPauseAndContinue = false;
this.CanShutdown = false;
this.CanStop = true;

if (!EventLog.SourceExists("Informer Watchguard"))
EventLog.CreateEventSource("Informer Watchguard", "Application");
}

/// <summary>
/// The Main Thread: This is where your Service is Run.
/// </summary>
static void Main()
{
ServiceBase.Run(new WindowsService());
}

/// <summary>
/// Dispose of objects that need it here.
/// </summary>
/// <param name="disposing">Whether or not disposing is going on.</param>
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}

/// <summary>
/// OnStart: Put startup code here
/// - Start threads, get inital data, etc.
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{

base.OnStart(args);

MyLogEvent("Init");

mWorker = new Thread(WatchServices);
mWorker.Start();

}

/// <summary>
/// OnStop: Put your stop code here
/// - Stop threads, set final data, etc.
/// </summary>
protected override void OnStop()
{

mStop.Set();
mWorker.Join();

base.OnStop();

}

/// <summary>
/// OnSessionChange(): To handle a change event from a Terminal Server session.
/// Useful if you need to determine when a user logs in remotely or logs off,
/// or when someone logs into the console.
/// </summary>
/// <param name="changeDescription"></param>
protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
base.OnSessionChange(changeDescription);
}

private void WatchServices()
{

string scName = "";

ServiceController[] scServices;
scServices = ServiceController.GetServices();

for (; ; )
{
// Run this code once every 10 seconds or stop right away if the service is stopped
if (mStop.WaitOne(10000)) return;
// Do work...
foreach (ServiceController scTemp in scServices)
{

scName = scTemp.ServiceName.ToString().ToLower();

if (scName == "InformerWatchguard") scName = ""; // don't do it for yourself

if (scName.Length > 8) scName = scName.Substring(0, 8);

if (scName == "informer")
{

ServiceController sc = new ServiceController(scTemp.ServiceName.ToString());

if (sc.Status == ServiceControllerStatus.Stopped)
{

sc.Start();
MyLogEvent("Found service " + scTemp.ServiceName.ToString() + " which has status: " + sc.Status + "\nRestarting Service...");

}

sc.Dispose();
sc = null;

}
}
}

}

private static void MyLogEvent(String Message)
{
// Create an eEventLog instance and assign its source.
EventLog myLog = new EventLog();
myLog.Source = "Informer Watchguard";

// Write an informational entry to the event log.
myLog.WriteEntry(Message);
}
}
}

最佳答案

您的代码可能会在循环内抛出异常,但这些异常不会被捕获。因此,将代码更改如下以捕获异常:

if (scName == "informer")
{
try {
using(ServiceController sc = new ServiceController(scTemp.ServiceName.ToString())) {
if (sc.Status == ServiceControllerStatus.Stopped)
{
sc.Start();
MyLogEvent("Found service " + scTemp.ServiceName.ToString() + " which has status: " + sc.Status + "\nRestarting Service...");
}
}
} catch {
// Write debug log here
}
}

您可以在调查后删除外部 try/catch,留下 using 语句以确保即使内部抛出异常也会调用 Dispose。

关于c# - 运行 Windows 服务以观察服务运行增长内存(泄漏),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3779518/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com