我试图编写一个Windows服务,用于监视使用C#的IIS应用程序池的内存,CPU和当前请求数。我目前所拥有的(如下所示)目前并没有真正做到这一点。
下面显示的代码正确地汇集了IIS中托管的当前应用程序,但是当您尝试获取" cpu time"," memory"的性能计数器时,它会引发无效操作例外。看起来有些东西不见了。任何帮助将非常感谢。谢谢。
using Microsoft.Web.Administration;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ResourceMonitor.Infrastructure
{
public class PerformanceAggregator
{
private static readonly List<PerformanceCounterCategory> Processes = new List<PerformanceCounterCategory>();
private static readonly List<string> Instances = new List<string>();
private static string _category = "Web Service";
private static readonly Dictionary<string, List<PerformanceCounter>> Resources = new Dictionary<string, List<PerformanceCounter>>();
private static void InitializeCounters()
{
if (!Instances.Any())
return;
foreach (var instance in Instances)
{
var resources = new List<PerformanceCounter>();
// Memory, "% Committed Bytes In Use"
if (PerformanceCounterCategory.InstanceExists(instance, _category))
{
var cpuTime = new PerformanceCounter(_category, "% Processor Time", instance);
cpuTime.NextValue();
resources.Add(cpuTime);
}
if (PerformanceCounterCategory.InstanceExists(instance, _category))
{
var memory = new PerformanceCounter(_category, "% Committed Bytes In Use", instance);
memory.NextValue();
resources.Add(memory);
}
if (PerformanceCounterCategory.InstanceExists(instance, @"ASP.NET"))
{
var requests = new PerformanceCounter(@"ASP.NET", "requests current", instance, true);
requests.NextValue();
resources.Add(requests);
}
//add instances to resources dictionary
Resources.Add(instance, resources);
}
}
private static void LoadInstances()
{
if (!Processes.Any())
{
LoadPerformanceCategory(_category);
}
foreach (var counterCategory in Processes)
{
var instances = counterCategory.GetInstanceNames().ToList();
instances = instances.Where(a => a.IndexOf("_") != 0).ToList();
if(instances.Any())
Instances.AddRange(instances);
}
}
private static void LoadPerformanceCategory(string category)
{
var categories = PerformanceCounterCategory
.GetCategories()
.Where(a => a.CategoryName.Contains(category))
.ToList();
if (categories.Any())
{
Processes.AddRange(categories);
}
}
public static bool Load(string service)
{
try
{
_category = service;
LoadPerformanceCategory(service);
LoadInstances();
//initialize counters
InitializeCounters();
return true;
}
catch (Exception e)
{
throw;
}
}
public static List<Resource> PoolResource()
{
var computedResources = new List<Resource>();
if(Resources != null && Resources.Any())
{
foreach (var resource in Resources)
{
var computedResource = new Resource
{
Name = resource.Key,
RecordedAt = DateTime.Now
};
foreach (var counter in resource.Value)
{
var value = counter.NextValue();
if (counter.CategoryName == "Process")
{
value = (value / Environment.ProcessorCount);
computedResource.CurrentCpu = value;
}
if (counter.CategoryName == "Memory")
{
value = counter.NextValue();
computedResource.CurrentMemory = value;
}
if (counter.CategoryName != "ASP.NET")
continue;
value = counter.NextValue();
computedResource.RequestCount = value;
}
computedResources.Add(computedResource);
}
}
return computedResources;
}
}
}