блокировка внутри простого свойства - может ли он зайти в тупик? - PullRequest
1 голос
/ 12 сентября 2011

Вопросы:

  1. Могу ли я заблокировать этот код?Является ли свойство IsMouseInside потокобезопасным?
  2. Имеет ли смысл использование переменной копирования?

PS: поток пользовательского интерфейса обновляет IsMouseInside.Другой поток будет читать его значение несколько раз

    public Class Test    
    {

    private readonly object isMouseInsideLocker = new object();
    private bool isMouseInside = false;

    public bool IsMouseInside
    {
        get
        {
            bool copy;
            lock (this.isMouseInsideLocker)
                copy = this.isMouseInside;
            return copy;
        }
        set
        {
            lock (this.isMouseInsideLocker)
                this.isMouseInside = value;
        }
    }

    private void lblProcessTime_MouseEnter(object sender, EventArgs e)
    {
        IsMouseInside = true;
    }

    private void lblProcessTime_MouseLeave(object sender, EventArgs e)
    {
        IsMouseInside = false;
    }
}

Ответы [ 4 ]

3 голосов
/ 12 сентября 2011
  1. Нет, вы не можете.
  2. Это не так.Всего return isMouseInside;
2 голосов
/ 12 сентября 2011

Нет, это не может тупик; есть только один объект блокировки, и не существует точки расширения, которая позволила бы вам сделать что-то грязное, пока блокировка удерживается. Однако, если вы используете блокировку, вам, вероятно, следует прояснить, каких сценариев вы пытаетесь избежать. Хотя значение на самом деле очень тонкое, мне интересно, может ли volatile работать здесь без необходимости каких-либо блокировок. Или Interlocked на int, который всегда либо 0, либо 1.

Но, конечно, похоже, что это сработает; В любом случае, bool всегда атомарен, поэтому блокировка в действительности действует только как барьер памяти, избегая проблем с кешем (следовательно, почему volatile также может работать). И помните, что каждый раз, когда вы получаете значение, оно устарело и, возможно, уже неверно. Это было правдой в момент чтения, хотя.

1 голос
/ 12 сентября 2011
  1. Вы не можете заблокировать - вы блокируете один и тот же объект.
  2. Это не имеет смысла для меня. Кроме того, блокировка не имеет смысла - я не думаю, что вы достигнете ничего с этим.

Какова цель?

0 голосов
/ 12 сентября 2011

Вы можете иметь взаимоблокировку только в том случае, если у вас есть две разные блокировки A и B, которые две разные нити пытаются получить в разном порядке - поскольку у вас есть только одна блокировка, вы в безопасности.

Также имейте в видучто блокировка C # (которая является синтаксическим сахаром для использования Monitor ) равна reentrant - один поток не может зайти в тупик, так как он может повторно войти в блокировку столько раз, сколько он хочет, после того как он изначальноприобрел его.

...