[英]How to fix CA Dispose objects before losing scope?
CA throw the following message: CA抛出以下消息:
CA2000 Dispose objects before losing scope.
In method 'GetMatchingJobsDeferred(BackgroundJobSearchParameters)',
object '<>g__initLocal0' is not disposed along all exception paths.
Call System.IDisposable.Dispose on object '<>g__initLocal0' before
all references to it are out of scope.
I have disposable type CompositeCollection
. 我有一次性类型CompositeCollection
。
public sealed class CompositeCollection<T> : IEnumerable<T>, IDisposable
{
private readonly List<IEnumerable<T>> _enumerables = new List<IEnumerable<T>>();
private readonly List<IDisposable> _disposables = new List<IDisposable>();
public void Add(IEnumerable<T> enumerable)
{
_enumerables.Add(enumerable);
}
public void Add(IDeferredResultCollection<T> deferredResultCollection)
{
_enumerables.Add(deferredResultCollection);
_disposables.Add(deferredResultCollection);
}
public IEnumerator<T> GetEnumerator()
{
return _enumerables.Aggregate((results, enumerable) => results.Concat(enumerable)).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Dispose()
{
foreach (var item in _disposables)
{
item.Dispose();
}
}
}
And that how I used it: 以及我如何使用它:
public IDeferredResultCollection<BackgroundJobInfoLight> GetMatchingJobsDeferred(BackgroundJobSearchParameters jobSearchParameters)
{
var memoryLocatedJobs = GetInMemoryJobs(jobSearchParameters);
var databaseLocatedJobs = GetInDatabaseJobsDeferred(jobSearchParameters, memoryLocatedJobs);
return new CompositeCollection<BackgroundJobInfoLight>
{
memoryLocatedJobs,
databaseLocatedJobs
};
}
I have exception when return
statement called. 调用return
语句时出现异常。 How to fix that? 如何解决?
I add try catch
and it doesn't help 我添加try catch
,但没有帮助
public IDeferredResultCollection<BackgroundJobInfoLight> GetMatchingJobsDeferred(BackgroundJobSearchParameters jobSearchParameters)
{
CompositeCollection<BackgroundJobInfoLight> deferredJobs = null;
DeferredResultCollection<BackgroundJobInfoLight> databaseLocatedJobs = null;
try
{
var memoryLocatedJobs = GetInMemoryJobs(jobSearchParameters);
databaseLocatedJobs = GetInDatabaseJobsDeferred(jobSearchParameters, memoryLocatedJobs);
deferredJobs = new CompositeCollection<BackgroundJobInfoLight> { memoryLocatedJobs, databaseLocatedJobs };
return deferredJobs;
}
catch
{
if (databaseLocatedJobs != null)
{
databaseLocatedJobs.Dispose();
}
if (deferredJobs != null)
{
deferredJobs.Dispose();
}
throw;
}
}
When returning the disposable objects, it should be the responsibility of the caller code to Dispose
the object. 返回一次性物品时,调用者代码有责任Dispose
该物品。 Had the Disposed
been called inside the method itself, the disposed object will return to the caller method, ( wont be of any use ). 如果在方法本身内部调用了Disposed
则已处理对象将返回到调用方方法( 不会有任何用处 )。
In that case it is safe to supress the warning. 在这种情况下,禁止警告是安全的。
BUT what if the exception occurred in this method? 但是如果此方法中发生异常怎么办?
If a disposable object is not explicitly disposed before all references to it are out of scope, the object will be disposed at some indeterminate time when the garbage collector runs the finalizer of the object. 如果在所有对它的引用超出范围之前未明确处理可弃对象,则当垃圾收集器运行该对象的终结器时,该对象将在不确定的时间被弃置。 Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead. 因为可能发生异常事件,这将阻止对象的终结器运行,所以应改为显式处置该对象。 MSDN MSDN
So, if you anticipate any exception in the method, you should have this code in try...catch
block and in catch
block you should call Dispose()
checking if the object is not null. 因此,如果您预计该方法中会出现任何异常,则应在try...catch
块中包含此代码,并在catch
块中应调用Dispose()
检查对象是否不为null。
And when you are not returning IDisposable
you can use using
statement or try...finally
and call dispose in finally
而当你没有返回IDisposable
,您可以使用using
语句或try...finally
和呼叫处理的finally
Why are you keeping items in to different list variables? 为什么将项目保留在不同的列表变量中? It may have something to do with your issue. 这可能与您的问题有关。 Keep it DRY Store them in one list and safely cast to what you are looking for. 保持干燥,将它们存储在一个列表中,然后安全地投射到您要查找的内容中。
IDisposable myDispType = myEnumarableType as IDisposable;
If (myDispType != null)
{//your logic here}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.