使用全局高速缓存时,如何修复CA2000 IDisposable C#编译器警告

Dom*_*icz 6 c# code-analysis idisposable visual-studio-2010 ca2000

CA2000是关于IDisposable接口的警告:

CA2000:Microsoft.Reliability:在方法'ImportProcessor.GetContext(string)'中,在对所有引用超出范围之前,在对象'c'上调用System.IDisposable.Dispose.

我的方法用于存储上下文缓存,如下所示:

public class RegionContext : IDisposable { /* Implement Dispose() here */ } 

private Dictionary<string, RegionContext> contextCache = new ..... ();

public RegionContext GetContext(string regionCode)
{
    RegionContext rc = null;

    if (!this.contextCache.TryGetValue(regionCode.ToUpper(), out rc))
    {
        rc = new RegionContext(regionCode);
        this.contextCache.Add(regionCode.ToUpper(), rc);
    }

    return rc;
}
Run Code Online (Sandbox Code Playgroud)

你会在哪里使用using()修复此编译器警告的语句?

我的外部类实际上会迭代并处理contextCache其自己的实现中的内容.我要压制它,还是有办法正确摆脱这个警告?

Mic*_*eld 12

只要您具有IDisposable的返回值并且不处理方法抛出异常的情况,就会出现此CA2000警告.在这种情况下,调用者就不会得到你的对象的有效实例,所以它没有办法处理它.所以你必须这样做.

我假设如果你成功地将它从缓存中拉出来,你将不想处置该对象.在这种情况下,您需要执行以下操作以确保您可能在本地创建的对象在所有情况下都处理掉:

public RegionContext GetContext(string regionCode)
{
    RegionContext temp = null;
    RegionContext rc = null;

    try
    {
        if (!this.contextCache.TryGetValue(regionCode.ToUpper(), out rc))
        {
            temp = new RegionContext(regionCode);
            this.contextCache.Add(regionCode.ToUpper(), temp);

            rc = temp;
            temp = null;
        }

        return rc;
    }
    finally 
    {
        if ( temp != null ) 
        {
             temp.Dispose();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Nic*_*oiu 6

CA2000在这里抱怨的是,如果在尝试将其添加到缓存时出现异常,则该变量可能在未处置状态下"孤立".要彻底解决问题,您可以按如下方式添加try/catch(newContext仅使用该变量以便CA2000可以检测到修复):

public RegionContext GetContext(string regionCode)
{
    RegionContext rc = null;
    if (!this.contextCache.TryGetValue(regionCode.ToUpper(), out rc))
    {
        RegionContext newContext = new RegionContext(regionCode);
        try
        {
            this.contextCache.Add(regionCode.ToUpper(), newContext);
        }
        catch
        {
            newContext.Dispose();
            throw;
        }

        rc = newContext;
    }

    return rc;
}
Run Code Online (Sandbox Code Playgroud)

就个人而言,在大多数情况下,我发现这种事情有些荒谬,但是ymmv ......