我有一个ASP.NET应用程序,它通过创建和写入自定义性能计数器来跟踪统计信息.有时,我会在错误日志中看到指示计数器无法打开,因为它们已在当前进程中使用过.我认为这是由于我的.NE
柜台建设:
PerformanceCounter pc = new PerformanceCounter(); pc.CategoryName = category_name; pc.CounterName = counter_name; pc.ReadOnly = false; pc.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; pc.InstanceName = instance_name;
柜台使用:
pc.Increment()
[2009年3月26日更新]
收到的错误消息是:
实例’_lm_w3svc_1_root_myapp’已存在,其生命周期为Process.在删除它或使用它的进程退出之前,它不能重新创建或重用.
已存在具有生命周期的过程.
我尝试通过初始化性能计数器并在瞬态AppDomain中写入其中一个来复制控制台应用程序中的异常.然后我卸载AppDomain并在第二个Appdomain中再次执行(相同的过程).他们都成功了.我现在不确定究竟是什么原因,我对ASP.NET中AppDomain回收的假设似乎是错误的.
IIRC,IIS不会确保您的第一个AppDomain在开始第二个AppDomain之前关闭,特别是当您手动或自动回收它时.我相信当启动回收时,第一个AppDomain首先被实例化,一旦成功,新的传入请求被引导到它,然后IIS等待第一个AppDomain(被关闭的那个)完成任何请求它具有.结果是两个AppDomain存在重叠,两者都具有相同的instance_name值.
然而,并非所有问题都得到解决我通过将进程ID作为实例名称的一部分包含在我的代码中更正了此问题.但它似乎引入了另一个问题 – 我认为是一个进程范围的性能计数器似乎永远不会在没有重新启动计算机的情况下消失. (这可能是我的错误,所以YMMV).
这是我创建实例名称的例程:
private static string GetFriendlyInstanceName() { string friendlyName = AppDomain.CurrentDomain.FriendlyName; int dashPosition = friendlyName.IndexOf('-'); if (dashPosition > 0) { friendlyName = friendlyName.Substring(0, dashPosition); } friendlyName = friendlyName.TrimStart('_'); string processID = Process.GetCurrentProcess().Id.ToString(); string processName = Process.GetCurrentProcess().ProcessName; string instanceName = processName + " " + processID + " " + friendlyName.Replace('/', '_').Trim('_').Trim(); return instanceName; }