Search code examples
c#warningsdisposefxcop

CA2000: Dispose object warning


I have the following method:

    public byte[] HtmlToDoc(string hmtl, string userId)
    {
        byte[] data;
        var auditor = new ServiceAuditor
        {
            User = userId
        };
        try
        {
            using (var tx = new ServerText())
            {
                tx.Create();
                tx.Load(Server.HtmlDecode(hmtl), StringStreamType.HTMLFormat);
                tx.Save(out data, BinaryStreamType.MSWord);
            }
        }
        catch (Exception e)
        {
            auditor.Errormessage = e.Message + "/n " + e.StackTrace;
            data = new byte[0];
        }
        finally
        {
            auditor.Save();
            auditor.Dispose();
        }
        return data;
    }

and I receive the following warning during compilation:

warning CA2000: Microsoft.Reliability : In method 'DocCreator.HtmlToDoc(string, string)', object 'new ServiceAuditor()' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'new ServiceAuditor()' before all references to it are out of scope.

The weird thing is that I don't see why it is complaining even though I am disposing the object. Could you point where is the issue?


Solution

  • The issue you have is this line:

    auditor.Save();
    

    If that throws an exception, the next line won't run which is responsible for disposing your auditor object. So you could wrap the Save call in another try/catch, but really you should just rely on the using statement to do this for you as that implicitly calls the Dispose method, for example:

    public byte[] HtmlToDoc(string hmtl, string userId)
    {
        byte[] data;
    
        //Add using statement here and wrap it around the rest of the code
        using(var auditor = new ServiceAuditor { User = userId })
        {
            try
            {
                using (var tx = new ServerText())
                {
                    tx.Create();
                    tx.Load(Server.HtmlDecode(hmtl), StringStreamType.HTMLFormat);
                    tx.Save(out data, BinaryStreamType.MSWord);
                }
            }
            catch (Exception e)
            {
                auditor.Errormessage = e.Message + "/n " + e.StackTrace;
                data = new byte[0];
            }
            finally
            {
                auditor.Save();
                //No need to manually dispose here any more
            }
        }
    
        return data;
    }