Блокировка элемента управления winforms - PullRequest
4 голосов
/ 10 августа 2009

Мне нужно убедиться, что, как только выполнение попадет в метод, управление, полученное этим методом, не изменится другим потоком. По сути, я думал примерно так:

private void doSomeWork(Control control) {
    lock (control) {
        // do some stuff with the control...
    }
}

Это плохая идея?

Edit:

На самом деле, я пытаюсь убедиться, что элемент управления не будет удален другим потоком, пока я выполняю некоторые методы элемента управления (которые, кстати, будут выполняться с помощью отражения).

Ответы [ 4 ]

3 голосов
/ 10 августа 2009

В хорошо работающем приложении элементы управления окнами форм уже ограничены только одним потоком. Если какой-либо поток попытается получить доступ к элементу управления, созданному в другом потоке, возникнет исключение.

В вашем коде нет ничего плохого, просто знайте, что сейчас он в основном бесполезен, если вы не взламываете свой путь через защиту (что возможно).

Обычно, когда данные создаются или обрабатываются в рабочем потоке, рабочий поток отправляет событие в поток пользовательского интерфейса для обновления пользовательского интерфейса. Рабочий поток ни в коем случае не должен обновлять сам интерфейс, он автоматически завершится ошибкой.

0 голосов
/ 10 августа 2009

Это полностью зависит от того, что вы подразумеваете под «не изменилось».

Если вы имеете в виду «любой другой поток не может никоим образом изменить этот элемент управления», то блокировка работает не так.

Замок в этом смысле не похож на обычный замок на двери в дом. Это больше похоже на маленькую желтую заметку с надписью «Заблокировано». Пока другие потоки читают заметку и соблюдают то, что она говорит, все должно быть в порядке, но любой другой поток, который вообще не заботится о заметке, не сможет помешать вашему контролю.

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

Вместо этого вы должны направлять всю работу над элементом управления в главный поток с помощью метода Invoke для элемента управления.

0 голосов
/ 10 августа 2009

Не имею большого опыта работы с потоками, но, возможно, я предложу вам запустить Контроль формы в новом потоке, используя анонимный делегат:

t= new Thread(delegate() {
    MyMethodToInvokeTheWinFormControl();
   });

t.Start();
0 голосов
/ 10 августа 2009

На самом деле, Фернандо, это неплохая идея, но это неправильный взгляд на блокировку. Вам нужно внимательно прочитать, что делает оператор блокировки в .Net:

http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx

Я думаю, что из вашего утверждения вы ожидаете, что весь объект будет заблокирован или каким-то образом сделан безопасным для потоков, потому что сам объект используется в заблокированном блоке кода. На самом деле происходит то, что блок кода блокируется и не может выполняться двумя или более потоками одновременно. Если этот блок кода - единственное место, где вы собираетесь работать с элементом управления, то все в порядке, в противном случае вам нужно будет выполнить синхронизирующие блокировки для самого объекта.

...