Заявление о блокировке, очевидно, не защищает критический код - PullRequest
0 голосов
/ 15 января 2020

Проблема: я использую C# оператор блокировки для защиты моей переменной '_NextId' при ее увеличении и назначении ее нового значения. Я не хочу, чтобы какие-либо другие потоки прерывали и зацепляли значение до тех пор, пока приращение не завершилось.

К сожалению , это не работает, потому что я получаю дубликаты при запуске это параллельно l oop. Это указывает на то, что другому потоку удалось проникнуть в мой защищенный код.

Вот код, который не работает должным образом:

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 , который доказывает, что дубликаты созданы. Я интерпретирую этот результат как указание на то, что блокировка работает не так, как я ожидал. Скрипка Do tNet запускает приведенный выше код параллельно l oop и затем считает, сколько дубликатов было создано. Если вы запустите его, он напечатает сообщение, показывающее количество дубликатов.

Ответы [ 2 ]

3 голосов
/ 15 января 2020

В вашем коде для каждого виджета создается отдельная _LockToken.

Попробуйте добавить модификатор static к _LockToken, чтобы все экземпляры класса Widget ссылались на тот же «токен блокировки».

2 голосов
/ 15 января 2020

Вы должны объявить переменную _LockToken как static, чтобы обеспечить блокировку одного и того же объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...