【问题标题】:Why expression is always true for 'double-checked-locking'?为什么“双重检查锁定”的表达式总是正确的?
【发布时间】:2011-04-18 20:58:43
【问题描述】:

我有单例对象“服务”和两种初始化和释放它的方法:

public class BaseService
{
    protected static readonly object StaticLockObject = new object();
}

public abstract class WebServiceBase<TService> : BaseService
    where TService : System.Web.Services.Protocols.SoapHttpClientProtocol, new()
{
    protected static void EnsureServiceIsOpened()
    {
        if (Service == null)
        {
            lock (StaticLockObject)
            {
                if (Service == null)
                {
                    Service = new TService();
                }
            }
        }
    }

    protected static void EnsureServiceIsClosed()
    {
        if (Service != null)
        {
            lock (StaticLockObject)
            {
                if (Service != null) // Why expression is always true
                {
                    Service.Dispose();
                    Service = null;
                }
            }
        }
    }

对于带有注释 resharper 的行(我使用 5.1 版)显示提到的警告...

问题 1: 为什么?

问题 2: 为什么在 'EnsureServiceIsOpened' 方法中不显示“类似”消息?

谢谢。

【问题讨论】:

    标签: c# singleton resharper


    【解决方案1】:

    Resharper 对代码进行了有限的分析,发现两个嵌套的if 语句检查完全相同。在单线程环境中,resharper 的评论完全正确 - 在第一个 if 之后,Service 不可能是 null。当然,在多线程环境中,这并不适用,因为 Service 可以从外部更改。在这种情况下,您应该为 resharper 注释代码或隐藏此文件的消息,因为它在多线程环境中不成立。

    【讨论】:

    • 单线程应用程序不会破坏您的代码 - 为什么这是一个 警告 让我感到困惑。 ://
    • 因为它可能会发生。代码分析只能到此为止 - 这就是出现此警告的原因。
    • 我对 Resharper 显示的这个没有问题,我认为这不应该是一个警告。 :)
    【解决方案2】:

    Resharper 似乎在此分析中犯了一个错误。由于Service 不是局部变量,它无法知道该表达式将始终为真。

    第一个版本没有出现错误的原因可能是因为双重检查锁定习语很常见,而且这是它的常用形式。他们可能针对这种情况进行了测试并删除了错误的警告。

    EnsureServiceIsClosed 中显示的技术并不常见,因为它包含竞争条件。另一个线程可能正在使用由Service 指示的对象,同时或之后处理它。如果使用服务的代码在StaticLockObject 上锁定,这是不可能的,但如果它确实获得了锁定,那么就没有理由在创建和处置对象时进行所有这些双重检查锁定。因此,几乎可以肯定这段代码是有缺陷的。

    【讨论】:

      【解决方案3】:

      这是 ReSharper 5.X 代码分析引擎中的错误。 在 ReSharper 6.0 中已修复。

      顺便说一句,ReSharper 6 带来了更多双锁模式分析的东西 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-12
        • 2021-10-25
        相关资源
        最近更新 更多