Memory leaks ManagementObjectCollection计数属性泄漏?

Memory leaks ManagementObjectCollection计数属性泄漏?,memory-leaks,wmi,idisposable,enumerator,Memory Leaks,Wmi,Idisposable,Enumerator,就在最近,我的几个同事帮助缩小了内存泄漏的范围。其中一个问题是在微软的代码中发现的。这是来自反射器的,表明枚举数将泄漏 此处count属性调用getenumerator,但从不检查Idisposable: public int Count { get { if (this.isDisposed) { throw new ObjectDisposedException(name); } int

就在最近,我的几个同事帮助缩小了内存泄漏的范围。其中一个问题是在微软的代码中发现的。这是来自反射器的,表明枚举数将泄漏

此处count属性调用getenumerator,但从不检查Idisposable:

public int Count
{
    get
    {
        if (this.isDisposed)
        {
            throw new ObjectDisposedException(name);
        }
        int num = 0;
        IEnumerator enumerator = this.GetEnumerator();
        while (enumerator.MoveNext())
        {
            num++;
        }
        return num;
    }
}
public class ManagementObjectEnumerator : IEnumerator, IDisposable
{
    // Fields
    private bool atEndOfCollection;
    private uint cachedCount;
    private IWbemClassObjectFreeThreaded[] cachedObjects;
    private int cacheIndex;
    private ManagementObjectCollection collectionObject;
    private IEnumWbemClassObject enumWbem;
    private bool isDisposed;
    private static readonly string name;

    // Methods
    static ManagementObjectEnumerator();
    internal ManagementObjectEnumerator(ManagementObjectCollection collectionObject, IEnumWbemClassObject enumWbem);
    public void Dispose();
    protected override void Finalize();
    public bool MoveNext();
    public void Reset();

    // Properties
    public ManagementBaseObject Current { get; }
    object IEnumerator.Current { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
}
这是ManagementObjectCollection的GetEnumerator,用于显示返回的类型是ManagementObjectEnumerator

public ManagementObjectEnumerator GetEnumerator()
{
    if (this.isDisposed)
    {
        throw new ObjectDisposedException(name);
    }
    if (!this.options.Rewindable)
    {
        return new ManagementObjectEnumerator(this, this.enumWbem);
    }
    IEnumWbemClassObject ppEnum = null;
    int errorCode = 0;
    try
    {
        errorCode = this.scope.GetSecuredIEnumWbemClassObjectHandler(this.enumWbem).Clone_(ref ppEnum);
        if ((errorCode & 0x80000000L) == 0L)
        {
            errorCode = this.scope.GetSecuredIEnumWbemClassObjectHandler(ppEnum).Reset_();
        }
    }
    catch (COMException exception)
    {
        ManagementException.ThrowWithExtendedInfo(exception);
    }
    if ((errorCode & 0xfffff000L) == 0x80041000L)
    {
        ManagementException.ThrowWithExtendedInfo((ManagementStatus) errorCode);
    }
    else if ((errorCode & 0x80000000L) != 0L)
    {
        Marshal.ThrowExceptionForHR(errorCode);
    }
    return new ManagementObjectEnumerator(this, ppEnum);
}
这表明它是一次性的:

public int Count
{
    get
    {
        if (this.isDisposed)
        {
            throw new ObjectDisposedException(name);
        }
        int num = 0;
        IEnumerator enumerator = this.GetEnumerator();
        while (enumerator.MoveNext())
        {
            num++;
        }
        return num;
    }
}
public class ManagementObjectEnumerator : IEnumerator, IDisposable
{
    // Fields
    private bool atEndOfCollection;
    private uint cachedCount;
    private IWbemClassObjectFreeThreaded[] cachedObjects;
    private int cacheIndex;
    private ManagementObjectCollection collectionObject;
    private IEnumWbemClassObject enumWbem;
    private bool isDisposed;
    private static readonly string name;

    // Methods
    static ManagementObjectEnumerator();
    internal ManagementObjectEnumerator(ManagementObjectCollection collectionObject, IEnumWbemClassObject enumWbem);
    public void Dispose();
    protected override void Finalize();
    public bool MoveNext();
    public void Reset();

    // Properties
    public ManagementBaseObject Current { get; }
    object IEnumerator.Current { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
}
尽管foreach语句正确地处理了一次性枚举数(http://msdn.microsoft.com/en-us/library/aa664754(v=vs.71).aspx),这并不意味着将使用枚举器的唯一情况是在foreach循环中

我知道您可以跳过count属性,自己使用枚举器滚动获取集合中对象数的机制,但问题是这会泄漏多少非托管内存