C#锁和代码分析警告CA2002

在我的应用程序中,我有一个表单启动同步过程,并且出于许多原因,我希望一次只允许一次同步运行。 所以我在表单中添加了一个静态bool字段,指示同步是否正在进行,并添加了一个锁,将该字段设置为true,如果它尚未设置,以便第一个线程可以开始同步,但是当它运行每个其他线程将尝试启动它将终止。

我的代码是这样的:

internal partial class SynchronizationForm : Form
{
    private static volatile bool workInProgress;

    private void SynchronizationForm_Shown(object sender, EventArgs e)
    {
        lock (typeof(SynchronizationForm))
        {
            if (!workInProgress)
            {
                workInProgress = true;
            }
            else
            {
                this.Close();
            }
        }
    }
}

这工作得很好,但是当我在我的项目上运行代码分析时,我收到以下警告消息:

CA2002:Microsoft.Reliability:'SynchronizationForm.SynchronizationForm_Shown(object,EventArgs)'锁定类型'Type'的引用。 将其替换为具有强身份的对象的锁。

任何人都可以向我解释我的代码出了什么问题,我该如何改进它才能使警告消失。 这个对象具有强烈的身份是什么意思?


什么是错误的是,你正在锁定一些公开的( typeof(SynchronizationForm) ),它可以在你的代码中任何地方访问,并且如果其他线程锁定在这个相同的东西上,你会遇到死锁。 一般来说,仅锁定私有静态对象是一个好主意:

private static object _syncRoot = new object();
...
lock (_syncRoot) 
{

}

这保证你只有SynchronizationForm可以拥有这个锁。


从MSDN解释规则

据说当一个对象可以跨应用程序域边界直接访问时,其身份较弱。 试图获得对具有弱身份的对象的锁的线程可以被锁定在同一对象上的不同应用程序域中的第二线程阻止。

由于您无法预测另一个AppDomain可能会占用什么锁,并且由于此类锁可能需要编组并且代价很高,所以此规则对我来说很有意义。


问题在于typeof(SynchronizationForm)不是私有锁对象,这意味着任何其他代码都可以使用它来锁定,这可能导致死锁。 例如,如果其他代码执行此操作:

var form = new SynchronizationForm();
lock(typeof(SynchronizationForm))
{
    form.SomeMethodThatCausesSynchronizationForm_ShownToBeCalled();
}

然后会发生死锁。 相反,你应该修改SynchronizationForm类中的私有锁对象并锁定它。

链接地址: http://www.djcxy.com/p/69033.html

上一篇: C# lock and code analysis warning CA2002

下一篇: Can you configure VS2008 Code Analysis to use a British English Dictionary?