有问题:我创建包装PerformanceCounter对象的单例助手对象。它实现了IDisposable ...但是现在我发现,当我关闭测试样本控制台主机应用程序时,计数器仍然在perfmon工具中可见(生产中我将托管在Windows服务中),并且仍在运行。如何在应用程序崩溃时处理
我想到Dispose在终结器中被调用,但是我没有处理托管资源 - 它们是PerformanceCounter对象。我该怎么做才能确保资源得到适当的释放?
谢谢你,帕维尔
有问题:我创建包装PerformanceCounter对象的单例助手对象。它实现了IDisposable ...但是现在我发现,当我关闭测试样本控制台主机应用程序时,计数器仍然在perfmon工具中可见(生产中我将托管在Windows服务中),并且仍在运行。如何在应用程序崩溃时处理
我想到Dispose在终结器中被调用,但是我没有处理托管资源 - 它们是PerformanceCounter对象。我该怎么做才能确保资源得到适当的释放?
谢谢你,帕维尔
这是性能计数器的正常行为。即使没有进程为它们生成数据,它们也是存在的全球“对象”。例如,您可以选择.NET perf计数器之一,即使机器上没有运行单个.NET程序。如果计数器正在主动生成数据,即使您没有正在运行的进程来更新其值,那么您可能选择了不适当的CounterType。
查看InstanceLifetime属性以查看过程值是否适合您的计数器。
检查下面的代码,看看如果你使用一次性模式。终结者应该明确地调用你的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);
}
}
Yeap。我遵循那种模式,真正的配置代码在 //配置管理资源 评论。所以当应用程序粉碎终结器被称为和处置设置为false。 – dragonfly 2010-06-22 12:09:18
@dragonfly - 如果您的应用程序崩溃,则不能保证终结器被调用。请参阅object.Finalize方法的备注部分:http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx – tvanfosson 2010-06-22 12:30:01
甚至更好:) thx。 – dragonfly 2010-06-23 09:18:47
如果您的应用程序崩溃了,那么确保非托管资源的处置方式就不多了。您应该正确实施一次性模式,并在您的非托管资源完成后处置(如果尚未完成)。通过这种方式,当服务关闭时您将释放资源,但在发生硬件崩溃时,您的代码可能无法运行。
我会建议,特别是如果您在Windows服务中托管可能会自动重新启动您的代码,您编写代码的期望可能会崩溃,将非托管资源留在并重用/回收它们可能。除此之外,你的编程也应该非常防守,以确保任何崩溃是罕见的(并且超出你的控制范围)。
这就是我一直在寻找的。我的计数器严格与实例相关,并且在进程退出时应该丢弃。 什么是模式我使用MultiInstance方法。 谢谢! – dragonfly 2010-06-23 08:45:52
呃,我很高兴早点:)柜台的InstanceLifetime是Global。但我不知道,如何将其更改为过程:/ 任何想法? – dragonfly 2010-06-23 09:02:44
例外: 实例初始化后,InstanceLifetime无法设置。在设置RawValue之前,您必须使用默认构造函数并手动设置CategoryName,InstanceName,CounterName,InstanceLifetime和ReadOnly属性。 – dragonfly 2010-06-23 09:09:11