CA1001在异步方法上实现IDisposable

时间:2018-01-04 12:35:39

标签: c# .net visual-studio async-await code-analysis

请考虑以下代码:

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()
    {
    }
}

当我在Visual Studio中运行代码分析时,我收到警告:

  

警告CA1001在测试时实施IDisposable。<请执行> d__0,因为它会创建以下IDisposable类型的成员:' Disposable'。

为什么我会收到此消息?一次性课程处理正确,我不会将其存放在任何地方。

此外,分析器似乎没问题:

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

2 个答案:

答案 0 :(得分:28)

那是因为编译器从您的异步方法生成状态机,并且该状态机类(在本例中名为<Do>d__0)包含类型Disposable的字段,但它本身并不实现{{ 1}}接口。分析器分析编译器生成的代码并没有多大意义(这个IDisposable类标有<Do>d__0属性)。幸运的是,代码分析器有一个设置可以避免编译器生成的代码:转到项目属性,&#34;代码分析&#34;选项卡并检查&#34;取消生成的代码&#34;的结果,此警告将消失。

答案 1 :(得分:10)

如果查看IL,您会发现创建了一个类<Do>d__0来处理异步内容:

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

稍后,此类创建一个Disposable实例:

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

这是触发CA1001的类,因为CA1001检查IL,并且生成的类没有实现IDisposable。您可以放心地忽略此特定类的CA1001警告。