当我运行以下代码时:
static void Main(string[] args)
{
if (!System.Diagnostics.EventLog.SourceExists("eventSource"))
{
System.Diagnostics.EventLog.CreateEventSource("eventSource", "");
}
System.Diagnostics.EventLog eventLog = new System.Diagnostics.EventLog();
eventLog.Source = "eventSource";
eventLog.Log = "";
for (int i = 0; i < 10000; i++)
{
Thread.Sleep(100);
eventLog.WriteEntry("test", EventLogEntryType.Information);
//I also tried the static method, the program still leaks
//System.Diagnostics.EventLog.WriteEntry("eventSource", "test", EventLogEntryType.Information);
}
Console.ReadKey();
}
内存使用量大约为1MB,但很快就会上升并且不会停止。为什么?
答案 0 :(得分:1)
我用于安装带有指定事件日志的Windows服务的代码:
[RunInstaller(true)]
public partial class SampleServiceInstaller : System.Configuration.Install.Installer
{
private string SampleServiceName = string.Empty;
private string SampleLogName = string.Empty;
public SampleServiceInstaller()
{
this.SampleServiceName = "SampleService";
this.SampleLogName = this.SampleServiceName + "Log";
ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();
serviceProcessInstaller.Password = null;
serviceProcessInstaller.Username = null;
serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
ServiceInstaller serviceInstaller = new ServiceInstaller();
//This must be identical to the WindowsService.ServiceBase name
// set in the constructor of WindowsService.cs
serviceInstaller.ServiceName = this.SampleServiceName;
serviceInstaller.DisplayName = this.SampleServiceName;
serviceInstaller.StartType = ServiceStartMode.Automatic;
serviceInstaller.Description = "Sample Windows Service";
// kill the default event log installer
serviceInstaller.Installers.Clear();
// Create Event Source and Event Log
// This recreates the log every time the service is reinstaled (old messages are lost)
if (EventLog.SourceExists(this.SampleServiceName)) EventLog.DeleteEventSource(this.SampleServiceName);
System.Diagnostics.EventLogInstaller logInstaller = new System.Diagnostics.EventLogInstaller();
logInstaller.Source = this.SampleServiceName; // use same as ServiceName
logInstaller.Log = this.SampleLogName; //can't be the same as service name
// Add all installers
this.Installers.AddRange(new Installer[] {
serviceProcessInstaller, serviceInstaller, logInstaller
});
}
public override void Install(System.Collections.IDictionary savedState)
{
base.Install(savedState);
}
protected override void OnBeforeUninstall(System.Collections.IDictionary savedState)
{
base.OnBeforeUninstall(savedState);
}
服务代码:
public partial class SampleService : ServiceBase
{
/// <summary>
/// Designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Event log for the service
/// </summary>
EventLog serviceLog;
/// <summary>
/// Public Constructor for WindowsService.
/// - Initialization code here.
/// </summary>
public SampleService()
{
InitializeComponent();
}
/// <summary>
/// The Main Thread: list of services to run.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new SampleService() };
ServiceBase.Run(ServicesToRun);
}
/// <summary>
/// Startup code
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
base.OnStart(args);
//
// run your own start code here
//
serviceLog.WriteEntry("My service started", EventLogEntryType.Information, 0);
}
/// <summary>
/// Stop code
/// </summary>
protected override void OnStop()
{
//
// run your own stop code here
//
serviceLog.WriteEntry("My service stopped", EventLogEntryType.Information, 0);
base.OnStop();
}
/// <summary>
/// Cleanup code
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
//
// do disposing here
//
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// Pause code
/// </summary>
protected override void OnPause()
{
base.OnPause();
//
// code to run if service pauses
//
}
/// <summary>
/// Continue code
/// </summary>
protected override void OnContinue()
{
base.OnContinue();
//
// code tu run when service continues after being paused
//
}
/// <summary>
/// Called when the System is shutting down
/// - when special handling
/// of code that deals with a system shutdown, such
/// as saving special data before shutdown is needed.
/// </summary>
protected override void OnShutdown()
{
//
// code tu run when system is shut down
//
base.OnShutdown();
}
/// <summary>
/// If sending a command to the service is needed
/// without the need for Remoting or Sockets,
/// this method is used to do custom methods.
/// int command = 128; //Some Arbitrary number between 128 & 256
/// ServiceController sc = new ServiceController("NameOfService");
/// sc.ExecuteCommand(command);
/// </summary>
/// <param name="command">Arbitrary Integer between 128 & 256</param>
protected override void OnCustomCommand(int command)
{
base.OnCustomCommand(command);
//
// handle custom code here
//
}
/// <summary>
/// Useful for detecting power status changes,
/// such as going into Suspend mode or Low Battery for laptops.
/// </summary>
/// <param name="powerStatus">The Power Broadcast Status
/// (BatteryLow, Suspend, etc.)</param>
protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus)
{
//
// handle power events here
//
return base.OnPowerEvent(powerStatus);
}
/// <summary>
/// To handle a change event
/// from a Terminal Server session.
/// Useful if determining
/// when a user logs in remotely or logs off,
/// or when someone logs into the console is needed.
/// </summary>
/// <param name="changeDescription">The Session Change
/// Event that occured.</param>
protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
//
// handle session change here
//
base.OnSessionChange(changeDescription);
}
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
// first 8 letters should be unique
this.ServiceName = "SampleService";
// if you want to log service event to log registered while installing the service
string newLogName = this.ServiceName + "Log";
string newSourceName = this.ServiceName;
if (!EventLog.SourceExists(newSourceName))
{
EventLog.CreateEventSource(newSourceName, newLogName);
}
serviceLog = new EventLog();
serviceLog.Source = newSourceName;
serviceLog.Log = newLogName;
// Causes log to be disposed when the service is disposed
components.Add(serviceLog);
// Flags set whether or not to handle that specific type of event.
this.CanHandlePowerEvent = true;
this.CanHandleSessionChangeEvent = true;
this.CanPauseAndContinue = true;
this.CanShutdown = true;
this.CanStop = true;
}
}