简体   繁体   English

如何在失去作用域之前修复CA Dispose对象?

[英]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.

相关问题 控制器上的“ CA2000在失去作用域之前先放置对象” - “CA2000 Dispose objects before losing scope” on controller “ CA2000丢失范围之前处置对象”原因不明 - “CA2000 Dispose objects before losing scope ” for unknown reason 我是否需要在这两个XmlDataSource对象上都调用.Dispose()? “ CA2000在失去作用域之前先处理对象”告诉我.Dispose() - Do I need to call .Dispose() on both of these XmlDataSource objects? “CA2000 Dispose objects before losing scope” tells me to .Dispose() it CA2000在失去DirectoryEntry对象的MVC项目中的作用域之前,先处理对象 - CA2000 Dispose objects before losing scope in MVC project for DirectoryEntry object FxCop 10.0找不到CA2000“在丢失范围之前处置对象” - FxCop 10.0 can't find CA2000 “Dispose objects before losing scope” C#CA2000:使用FileStream / XmlTextReader在丢失范围之前处置对象 - C# CA2000:Dispose objects before losing scope using FileStream/XmlTextReader 在失去作用域之前处置对象(SqlCommand) - Dispose objects before losing scope(SqlCommand) C#CA2000在丢失范围之前处置对象 - C# CA2000 Dispose Object Before Losing Scope 当我不处理我的MDI子窗体时,代码分析投诉“ CA2000在失去作用域之前先处理对象” - Code Analysis Complains about “CA2000 Dispose objects before losing scope” when I Don't Dispose My MDI Child Form 基于不适用于 System.Web.UI.Control 对象的 CA2000“在失去范围之前处理对象”创建自定义 FXCop 规则 - Creating a Custom FXCop Rule based on CA2000 “Dispose Objects Before Losing Scope” that doesn't apply to System.Web.UI.Control objects
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM