gpt4 book ai didi

c# - 是否有必要处置每个 ManagementObject?

转载 作者:太空狗 更新时间:2023-10-30 00:53:36 24 4
gpt4 key购买 nike

我注意到 ManagementObjectIDisposable,但它也是从 ManagementClass.GetInstances()ManagementObjectSearcher.Get() 返回的,这是否意味着我需要处置遇到的每个对象?

像这样:

ManagementObject ret;
foreach(ManagementObject mo in searcher.Get()) {
if( IsWhatIWant(mo) ) ret = mo;
else mo.Dispose();
}

进一步混淆这一点:ManagementBaseObject 中存在一个错误,它没有正确实现 IDisposable(参见 Using clause fails to call Dispose?),因此您需要自己调用它,或者使用正确调用它的包装器。

这很烦人,因为我周围有太多 ManagementObjectCollections

最佳答案

我创建了一个辅助对象来处理所有创建的管理对象:

public class ManagementObjectDisposer : IDisposable
{
private List<IDisposable> disposables = new List<IDisposable>();

/// <summary>
/// Workaround to dispose ManagementBaseObject properly.
/// See http://stackoverflow.com/questions/11896282
/// </summary>
/// <param name="disposable"></param>
public static void DisposeOne(IDisposable disposable)
{
ManagementBaseObject mbo = disposable as ManagementBaseObject;
if (mbo != null)
mbo.Dispose();
else
disposable.Dispose();
}

public void Dispose()
{
Exception firstException = null;
foreach (IDisposable d in Enumerable.Reverse(disposables))
{
try
{
DisposeOne(d);
}
catch (Exception ex)
{
if (firstException == null)
firstException = ex;
else
cvtLogger.GetLogger(this).Error($"Swallowing exception when disposing: {d.GetType()}", ex);
}
}
disposables.Clear();
if (firstException != null)
throw firstException;
}

public T Add<T>(T disposable) where T : IDisposable
{
disposables.Add(disposable);
return disposable;
}

/// <summary>
/// Helper for ManagementObjectSearcher with adding all objects to the disposables.
/// </summary>
/// <param name="query">The query string.</param>
public IEnumerable<ManagementBaseObject> Search(string query)
{
ManagementObjectSearcher searcher = this.Add(new ManagementObjectSearcher(query));
return EnumerateCollection(searcher.Get());
}

/// <summary>
/// Helper for adding ManagementObjectCollection and enumerating it.
/// </summary>
public IEnumerable<ManagementBaseObject> EnumerateCollection(ManagementObjectCollection collection)
{
this.Add(collection);
ManagementObjectCollection.ManagementObjectEnumerator enumerator = this.Add(collection.GetEnumerator());
while (enumerator.MoveNext())
yield return this.Add(enumerator.Current);
}
}

就像这样使用它:

using (var moDisposer = new ManagementObjectDisposer())
{
foreach (var mobj = moDisposer.Search("SELECT * FROM Win32_Processor")
Console.WriteLine(mobj["DeviceID"]);
}

注意:ManagementClass.GetInstances() 也很容易添加到 ManagementObjectDisposer

关于c# - 是否有必要处置每个 ManagementObject?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15697684/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com