【问题标题】:Lock Statement Apparently Not Protecting Critical CodeLock 语句显然不能保护关键代码
【发布时间】:2020-01-15 19:25:56
【问题描述】:

问题:我使用 C# lock 语句 来保护我的变量 '_NextId',当我增加它并分配它的新值时。在增量完成之前,我不希望任何其他线程中断和捕获该值。

不幸的是,它似乎不起作用,因为当我在并行循环中运行它时,我得到了重复。这向我表明,另一个线程设法潜入了我的受保护代码。

以下是无法按预期工作的代码:

public class Widget {
    private static int _NextId;
    private object _LockToken = new object();

    public Widget() {
        //I expected this lock to prevent any other thread from assigning its ID until we have
        //completed incrementing the member variable
        lock (_LockToken) {
            ID = ++_NextId;
        }
    }

    public int ID { get; private set; }
}

这里有一个指向DotNetFiddle 的链接,它证明已创建重复项。我将该结果解释为表明锁没有按我预期的方式工作。 DotNet fiddle 在并行循环中运行上面的代码,然后计算创建了多少重复 ID。如果你运行它,它将打印一条显示重复计数的消息。

【问题讨论】:

    标签: c# multithreading locking


    【解决方案1】:

    在您的代码中,正在为每个小部件创建不同的_LockToken

    尝试将static 修饰符添加到_LockToken,以便Widget 类的所有实例引用相同的“锁定令牌”。

    【讨论】:

    • 谢谢alxrcs,Tarik 比你回答我的问题要快一点。
    • 不用担心。很高兴看到你想通了。 :)
    【解决方案2】:

    您应该将_LockToken 变量声明为static,以确保对同一个对象进行锁定。

    【讨论】:

    • 感谢 Tarik,修复了它。
    猜你喜欢
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    相关资源
    最近更新 更多