Проверка пустой указатель перед событием, диспетчеризирующим … ориентированный на многопотоковое исполнение?

В Java все находится в форме класса.

Если вы хотите использовать любой объект, тогда у вас есть две фазы:

  1. Объявить
  2. Инициализация

Пример:

  • Объявление: Object a;
  • Инициализация: a=new Object();

То же самое для концепции массива

  • Объявление: Item i[]=new Item[5];
  • Инициализация: i[0]=new Item();

Если вы не дают секцию инициализации, тогда возникает NullpointerException.

35
задан Noctis 23 March 2015 в 01:23
поделиться

4 ответа

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

protected virtual void OnSomeEvent(EventArgs args) 
{
    EventHandler ev = SomeEvent;
    if (ev != null) ev(this, args);
}

Это работает потому что каждый раз, когда делегат добавлен к или удален из события с помощью реализаций по умолчанию добавления и удаляет средства доступа, Делегата. Объединение и Делегат. Удалите статические методы, используются. Каждый из этих методов возвращает новый экземпляр делегата, вместо того, чтобы изменить тот передал ему.

, Кроме того, присвоение ссылки на объект в.NET атомарное , и реализации по умолчанию добавления, и удалите средства доступа события, , синхронизировался . Таким образом, код выше успешно выполняется первым копированием многоадресного делегата от события до временной переменной. Любые изменения в SomeEvent после этой точки не будут влиять на копию, которую Вы сделали и сохранили. Таким образом можно теперь безопасно протестировать, были ли какие-либо делегаты зарегистрированы и впоследствии вызывают их.

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

, Например, если обработчик событий зависит от состояния, это уничтожается, как только обработчик отписан, тогда это решение могло бы вызвать код, который не может работать правильно. См. превосходная запись в блоге Eric Lippert для получения дополнительной информации. Кроме того, см. этот вопрос о StackOverflow и ответы .

РЕДАКТИРОВАНИЕ: Если Вы используете C# 6.0, то ответ Krzysztof похож на хороший способ пойти.

55
ответ дан RoadWarrior 27 November 2019 в 06:31
поделиться

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

public event EventHandler SomeEvent = delegate {};

Связанный вопрос: там оборотная сторона к добавлению анонимного пустого делегата на объявлении события?

22
ответ дан Community 27 November 2019 в 06:31
поделиться

Рекомендуемый путь немного отличается и использует временный файл следующим образом:

EventHandler tmpEvent = SomeEvent;
if (tmpEvent != null)
{
    tmpEvent();
}
4
ответ дан denis phillips 27 November 2019 в 06:31
поделиться

Более безопасный подход:


public class Test
{
    private EventHandler myEvent;
    private object eventLock = new object();

    private void OnMyEvent()
    {
        EventHandler handler;

        lock(this.eventLock)
        {
            handler = this.myEvent;
        }
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }

    public event MyEvent
    {
        add
        {
            lock(this.eventLock)
            {
                this.myEvent += value;
            }
        }
        remove
        {
            lock(this.eventLock)
            {
                this.myEvent -= value;
            }
        }

    }
}

- счет

3
ответ дан 27 November 2019 в 06:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: