C # Блокировка от событий - PullRequest
2 голосов
/ 05 апреля 2011

Есть ли в c # конструкция, которая похожа на lock {}, но работает при вызове из обработчика событий, т.е. ожидает завершения блока кода перед обработкой последующего события.

Проблема, с которой я столкнулся, заключается в том, что lock {} не позволяет другим потокам получить блокировку объекта, но если вызывается обработчик событий в том же потоке, выполнение кода в блоке блокировки прерывается, и новое событие обрабатывается перед возвратом к выполнению исходного кода.

object DoStuffLock = new object();

public void DoStuff()
{
    lock (DoStuffLock)
    {
         // Do stuff that we don't want to be interrupted,
         // but because it is called from an event handler 
         // it still can be interrupted despite the lock
    }
}

В настоящее время я работаю над этой проблемой (но это вряд ли идеально):

object DoStuffLock = new object();

// this gets called from an event, and therefore can be interrupted, 
// locking does not help, so launch separate thread
public void DoStuff()
{
    var x = new Thread(DoStuffInternal);
    x.Start();
}

private void DoStuffInternal()
{
    lock (DoStuffLock)
    {
         // Do stuff that we don't want to be interrupted
    }
}

Ответы [ 4 ]

3 голосов
/ 05 апреля 2011

Проблема, с которой я столкнулся, заключается в том, что lock {} не позволяет другим потокам получить блокировку объекта, но если обработчик событий в том же потоке называется

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

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

0 голосов
/ 05 апреля 2011

В операционных системах, таких как Windows, вы не можете делать какие-либо предположения о порядке обработки событий. Это может быть сделано только с операционными системами реального времени .

Что вы можете сделать в вашем случае, так это увеличить приоритет потока. Это должно дать вашей теме больше времени (по сравнению с другими темами). Более подробную информацию о приоритете потоков в .net можно найти здесь: http://msdn.microsoft.com/en-us/library/system.threading.threadpriority.aspx

0 голосов
/ 05 апреля 2011

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

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

0 голосов
/ 05 апреля 2011

Подумайте о коде блокировки, а не об объекте.

Используйте один и тот же объект блокировки для блокировки фрагментов кода, которые не могут быть введены одновременно.

Кроме того, блокировки не останавливают прерывание, они просто останавливают доступ к одному и тому же коду из двух потоков одновременно.

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