2010-06-22 66 views
2

有问题:我创建包装PerformanceCounter对象的单例助手对象。它实现了IDisposable ...但是现在我发现,当我关闭测试样本控制台主机应用程序时,计数器仍然在perfmon工具中可见(生产中我将托管在Windows服务中),并且仍在运行。如何在应用程序崩溃时处理

我想到Dispose在终结器中被调用,但是我没有处理托管资源 - 它们是PerformanceCounter对象。我该怎么做才能确保资源得到适当的释放?

谢谢你,帕维尔

回答

1

这是性能计数器的正常行为。即使没有进程为它们生成数据,它们也是存在的全球“对象”。例如,您可以选择.NET perf计数器之一,即使机器上没有运行单个.NET程序。如果计数器正在主动生成数据,即使您没有正在运行的进程来更新其值,那么您可能选择了不适当的CounterType。

查看InstanceLifetime属性以查看过程值是否适合您的计数器。

+0

这就是我一直在寻找的。我的计数器严格与实例相关,并且在进程退出时应该丢弃。 什么是模式我使用MultiInstance方法。 谢谢! – dragonfly 2010-06-23 08:45:52

+0

呃,我很高兴早点:)柜台的InstanceLifetime是Global。但我不知道,如何将其更改为过程:/ 任何想法? – dragonfly 2010-06-23 09:02:44

+0

例外: 实例初始化后,InstanceLifetime无法设置。在设置RawValue之前,您必须使用默认构造函数并手动设置CategoryName,InstanceName,CounterName,InstanceLifetime和ReadOnly属性。 – dragonfly 2010-06-23 09:09:11

1

检查下面的代码,看看如果你使用一次性模式。终结者应该明确地调用你的dispose方法。

class DisposableObject : IDisposable 
{ 
    public void Dispose() 
    { 
     this.Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      // dispose managed resources 
     } 
     // dispose unmanaged resources 
    } 

    ~DisposableObject() 
    { 
     this.Dispose(false); 
    } 
} 
+0

Yeap。我遵循那种模式,真正的配置代码在 //配置管理资源 评论。所以当应用程序粉碎终结器被称为和处置设置为false。 – dragonfly 2010-06-22 12:09:18

+0

@dragonfly - 如果您的应用程序崩溃,则不能保证终结器被调用。请参阅object.Finalize方法的备注部分:http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx – tvanfosson 2010-06-22 12:30:01

+0

甚至更​​好:) thx。 – dragonfly 2010-06-23 09:18:47

2

如果您的应用程序崩溃了,那么确保非托管资源的处置方式就不多了。您应该正确实施一次性模式,并在您的非托管资源完成后处置(如果尚未完成)。通过这种方式,当服务关闭时您将释放资源,但在发生硬件崩溃时,您的代码可能无法运行。

我会建议,特别是如果您在Windows服务中托管可能会自动重新启动您的代码,您编写代码的期望可能会崩溃,将非托管资源留在并重用/回收它们可能。除此之外,你的编程也应该非常防守,以确保任何崩溃是罕见的(并且超出你的控制范围)。