c # нужно вызвать событие, когда в области LOCK - PullRequest
3 голосов
/ 22 ноября 2010

У меня есть класс обработчика файлов, который перемещает xdoument в кеш, используя блокировку. Код Псуэдо:

public FetchDocument() {
    var xdoc = Cache[_Key1];
    if (xdoc == null) {
        lock(_lockobject) {
            // in case prev.thread has done upload will currth read waiting
            xdoc = Cache[_Key1];

            if (xdoc == null) {
               .... Code to grab from file and add to catch - works great.....
            }
        }
    }
    xdoc = Cache[_Key1];

}

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

Проблема в том, как вызвать события только для текущего (разблокированного) потока?

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

Спасибо

Martin

Ответы [ 2 ]

0 голосов
/ 22 ноября 2010

Если я правильно понимаю, вы хотите разрешить вызывающей стороне прервать кэширование документа.Это можно сделать, передав Func в метод FetchDocument, например:

public XDocument FetchDocument(FUnc<XDocument, bool> cacheNewDocument) {
    var xdoc;        
    lock(_lockobject) {
        // in case prev.thread has done upload will currth read waiting
        xdoc = Cache[_Key1];

        if (xdoc == null) {
           xdoc = .... Code to grab from file and add to catch - works great.....

           if (cacheNewDocument(xdoc)){
               Cache.Add(_Key1, xdoc)
           }
           else{
               return xdoc;
           }
        }
    }

    return xdoc;
}

Таким образом, ваш код может вызвать Func с соответствующими данными перед добавлением документа в кэш, и вызывающая сторона может вернуть true \значение false, чтобы получить семантику прерывания.

Это гораздо проще, чем использование события, и обеспечивает применение правила «как только запускать событие (я) только для семантики текущего (разблокированного) потока».

С другой стороны, хотя ваш исходный код является псевдокодом, вы получаете доступ к объекту Cache вне блокировки.Даже если эти разблокированные операции являются операциями чтения, коллекция может быть видоизменена внутри блокировки, и вы можете получить непредсказуемые результаты.Все операции с кешем должны выполняться в замке.

0 голосов
/ 22 ноября 2010

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

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

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