.NET: создает новый EventArgs каждый раз, когда событие запускает хорошую практику?

Например, у меня есть основной метод публикации события:

    protected virtual OnSomeEvent(EventArgs e)
    {
        var handler = SomeEvent;
        if (handler != null)
        {
            handler(this, e);
            // handler(this, new EventArgs());// EDIT: Yes it should be
                                           // handler(this, e),
                                           // ignore this one :D
        }
    }

Для производного класса, который переопределяет OnSomeEvent и генерирует дополнительное событие, когда оно стреляет:

    protected override OnSomeEvent(EventArgs e)
    {
        base.OnSomeEvent(e);

        if (ExtendedEvent != null)
        {
            OnExtendedEvent(e);
        }
    }

    protected void OnExtendedEvent(EventArgs e)
    {
       // some stuff done
       // new information the ExtendedEventArgs object needs 
       //  is not available until this point

       ExtendedEvent(this, new ExtendedEventArgs(someStuff, someOtherStuff));
    }

И если деривация продолжится как это, то она создаст новый полученный EventArgs для каждого поколения производного класса, который требует его. Однако это кажется различными деривациями EventArgs на.NET платформа не разработана, чтобы быть изменяемой (никакие методы set), это отговаривает объект сохранить единственный экземпляр EventArgs, и измените его, когда это идет.

Так каждый раз, когда событие как это стреляет, оно перераспределит память для всех включенных EventArgs объекты. В графическом интенсивном приложении, где событие может быть инициированными десятками времен в секунду (такой как OnPaint событие на управлении), это - действительно хорошая практика?

Если я вношу некоторые изменения в OnExtendedEvent() и сделайте ExtendedEventArgs изменяемый, таким образом, следующее возможно?

    protected ExtendedEventArgs extendedArgs = ExtendedEventArgs.Empty;
    protected void OnExtendedEvent(EventArgs e)
    {
       // some stuff done
       // new information the ExtendedEventArgs object needs 
       //  is not available until this point

       extendedArgs.someProperty1 = someStuff;
       extendedArgs.someProperty2 = someOtherStuff;

       ExtendedEvent(this, extendedArgs);
    }

Править: Зафиксированный пример кода, должно быть более ясным теперь.

8
задан Dan7 29 January 2010 в 02:29
поделиться

3 ответа

Я бы создал новый неизменный объект каждый раз, когда он Уволен, так как в аргументах события есть ценности.

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

Это возможно произойдет в многопоточных приложениях, но может даже произойти в одном потоке, как показано В следующем примере:

Первое событие выпускается со следующими значениями:

extendedArgs.someProperty1 = "Fire 1";
extendedArgs.someProperty2 = "Fire 1 Other Stuff";

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

extendedArgs.someProperty1 = "Fire 2";
extendedArgs.someProperty2 = "Fire 2 Other Stuff";

Все обработчики событий предназначены для второго события обрабатываются, и теперь мы вернемся к обработке остальных обработчиков событий для первого события.

Теперь, поскольку тот же объект используется, все обработчики событий для первого мероприятия теперь будут иметь «пожар 2» в качестве их SomeProperty1, поскольку второе событие перезагружает значения.

Как упомянутое @nobugz, не бойтесь создавать недолговечный мусор.

3
ответ дан 5 December 2019 в 19:00
поделиться

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

protected virtual OnSomeEvent(EventArgs e)
{
    var handler = SomeEvent;
    if (handler != null)
    {
        handler(this, e);
    }
}

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

5
ответ дан 5 December 2019 в 19:00
поделиться

Я немного запутался в вашем коде OnExtendedEvent - вы хотите переписать событие как SomeEvent?

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

someObject.SomeEvent += OnSomeEvent;
// ...
private void OnSomeEvent(object sender, EventArgs e)
{
    someObject.SomeEvent -= OnSomeEvent;
}

Если вы не следуете стандартной практике диспетчеризации, этот код бросит Исключение на сюрприз тому, кто использует ваш код.

1
ответ дан 5 December 2019 в 19:00
поделиться
Другие вопросы по тегам:

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