visual studio 2010 -在使用全局缓存时,如何修复CA2000 IDisposable c#编译器警告



CA2000是一个关于IDisposable接口的警告:

CA2000: Microsoft。可靠性:` ImportProcessor.GetContext(string) `,调用System.IDisposable.Dispose

在对象'c'的所有引用都超出作用域之前。

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

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;
}

您将在哪里使用using()语句来修复此编译器警告?

我的外部类实际上在它自己的实现中迭代和处置contextCache中的内容。我是否应该抑制它,或者是否有一种方法可以正确地摆脱这个警告?

只要您有一个不可处置的返回值,并且不处理方法抛出异常的情况,就会出现这个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();
        }
    }
}

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;
}

就我个人而言,我觉得这种事情在大多数情况下有点荒谬,但是,嗯……

Michael的解决方案在转换为VB.Net时似乎不起作用。在VS 2017下测试了以下两个函数:

    Public Function OpenStream(ByVal filePathName As String) As System.IO.FileStream
        Dim fileStream As System.IO.FileStream = Nothing
        Dim tempFileStream As System.IO.FileStream = Nothing
        If Not String.IsNullOrWhiteSpace(filePathName) Then
            Try
                tempFileStream = New System.IO.FileStream(filePathName, System.IO.FileMode.Open, System.IO.FileAccess.Read)
                fileStream = tempFileStream
            Catch
                tempFileStream?.Dispose()
                Throw
            End Try
        End If
        Return fileStream
    End Function
    Public Function OpenReader(ByVal filePathName As String) As System.IO.BinaryReader
        If String.IsNullOrWhiteSpace(filePathName) Then Throw New ArgumentNullException(NameOf(filePathName))
        If Not System.IO.File.Exists(filePathName) Then Throw New System.IO.FileNotFoundException("Failed opening a binary reader -- file not found.", filePathName)
        Dim tempReader As System.IO.BinaryReader = Nothing
        Dim reader As System.IO.BinaryReader = Nothing
        Dim stream As IO.FileStream = Nothing
        Try
            stream = Methods.OpenStream(filePathName)
            tempReader = New System.IO.BinaryReader(stream)
            reader = tempReader
        Catch
            stream?.Dispose()
            tempReader?.Dispose()
            Throw
        End Try
        Return reader
    End Function

相关内容

  • 没有找到相关文章

最新更新