C#锁定和代码分析警告CA2002

RaY*_*ell 7 c# code-analysis locking

在我的应用程序中,我有一个启动同步过程的表单,出于多种原因,我希望一次只允许一个同步运行.所以我在我的表单中添加了一个静态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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这很好用但是当我在我的项目上运行Code Analysis时,我收到以下警告消息:

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

任何人都可以向我解释我的代码有什么问题,如何改进它以使警告消失.对象具有强烈的身份意味着什么?

Dar*_*rov 9

有什么不对的是你锁定了一些public(typeof(SynchronizationForm)),它可以在你的代码中到处访问,如果某个其他线程锁定同一件事,你就会遇到死锁.一般来说,最好只锁定私有静态对象:

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

}
Run Code Online (Sandbox Code Playgroud)

这可以保证你只能SynchronizationForm拥有锁.


Dou*_*ean 6

MSDN解释规则

当一个对象可以跨应用程序域边界直接访问时,它被认为具有弱标识.尝试获取具有弱标识的对象的锁的线程可以被锁定在同一对象上的另一个应用程序域中的第二个线程阻止.

由于您无法预测另一个AppDomain可能会采取什么锁定,并且由于此类锁定可能需要进行编组,然后会很昂贵,因此这个规则对我来说很有意义.