Jan Muncinsky
Jan Muncinsky

Reputation: 4408

CA1001 implement IDisposable on async method

Consider following code:

public class Test
{
    public async Task Do()
    {
        await Task.Delay(200);

        using (var disposable = new Disposable())
        {
            disposable.Do();
        }
    }
}

public class Disposable : IDisposable
{
    public void Do()
    {
    }

    public void Dispose()
    {
    }
}

When I run a code analysis in Visual studio I get a warning:

Warning CA1001 Implement IDisposable on Test.< Do>d__0 because it creates members of the following IDisposable types: 'Disposable'.

Why do I get this message? Disposable class is disposed correctly and I don't store it anywhere.

Furthermore this seems to be OK for analyzer:

public class Test
{
    public void Do()
    {
        using (var disposable = new Disposable())
        {
            disposable.Do();
        }
    }
}

Upvotes: 32

Views: 2215

Answers (2)

Evk
Evk

Reputation: 101533

That's because compiler generates state machine from your async method, and that state machine class (named <Do>d__0 in this case) contains field of type Disposable but does not itself implements IDisposable interface. It doesn't make much sense for analyzer to analyze compiler generated code (and this <Do>d__0 class is marked with CompilerGenerated attribute). Fortunately, there is a setting for code analyzer to avoid compiler generated code: go to project properties, "Code Analysis" tab and check "Suppress results from generated code", and this warning will go away.

Upvotes: 29

Thomas Radioyes
Thomas Radioyes

Reputation: 249

If you look at the IL, you'll find that a class <Do>d__0 is created to handle the async stuff:

// Nested Types
.class nested private auto ansi sealed beforefieldinit '<Do>d__0'
    extends [mscorlib]System.Object
    implements [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine
{

Later on, this class creates an instance of Disposable:

IL_0074: newobj instance void ConsoleApp1.Disposable::.ctor()

That's the class that triggers CA1001 because CA1001 checks the IL, and the generated class does not implement IDisposable. You can safely disregard the CA1001 warning on this particular class.

Upvotes: 10

Related Questions