25
I'm using Visual Studio 2010 to target .NET 4.0 Client Profile. I have a C# class to detect when a given process starts/terminates. For this the class uses a ManagementEventWatcher, which is initialised as below; query, scope and watcher are class fields:
query = new WqlEventQuery();
query.EventClassName = "__InstanceOperationEvent";
query.WithinInterval = new TimeSpan(0, 0, 1);
query.Condition = "TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = 'notepad.exe'";
scope = new ManagementScope(@"\\.\root\CIMV2");
watcher = new ManagementEventWatcher(scope, query);
watcher.EventArrived += WatcherEventArrived;
watcher.Start();
The handler for event EventArrived looks like this:
private void WatcherEventArrived(object sender, EventArrivedEventArgs e)
{
string eventName;
var mbo = e.NewEvent;
eventName = mbo.ClassPath.ClassName;
mbo.Dispose();
if (eventName.CompareTo("__InstanceCreationEvent") == 0)
{
Console.WriteLine("Started");
}
else if (eventName.CompareTo("__InstanceDeletionEvent") == 0)
{
Console.WriteLine("Terminated");
}
}
This code is based on a CodeProject article. I added the call to mbo.Dispose() because it leaked memory: about 32 KB every time EventArrived is raised, once per second. The leak is obvious on both WinXP and Win7 (64-bit).
So far so good. Trying to be conscientious I added a try-finally clause, like this:
var mbo = e.NewEvent;
try
{
eventName = mbo.ClassPath.ClassName;
}
finally
{
mbo.Dispose();
}
No problem there. Better still, the C# using clause is more compact but equivalent:
using (var mbo = e.NewEvent)
{
eventName = mbo.ClassPath.ClassName;
}
Grea