Нужно ли создавать новый пользовательский eventarg каждый раз, когда событие запускается? - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть приложение WinForms, которое использует события с пользовательскими событиями для обновления панели состояния в MainForm.

Я объявляю свое событие в своем классе следующим образом:

Public Event BomNotLoaded As EventHandler(Of StatusEventArgs)

Когдасобытие запускается, я называю это так:

OnBomNotLoaded(New StatusEventArgs(2, "Please scan a SKU/UPC First!", Color.Red, Color.White))

Protected Overridable Sub OnBomNotLoaded(ByVal e As StatusEventArgs)
    RaiseEvent BomNotLoaded(Me, e)
End Sub

В коде MainForm у меня есть это:

Private Sub _station_BomNotLoaded(sender As Object, e As StatusEventArgs) Handles _station.BomNotLoaded
    SetStatus(e)
    _alert.InvalidScan()
End Sub

Затем метод SetStatus использует значения в StatusEventArgs для установкитекст метки, изображение, цвет метки и цвет текста метки.Изображение выводится из первого числа в виде кодового номера.

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

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

1 Ответ

0 голосов
/ 29 сентября 2018

По правде говоря, не должно быть проблем с созданием одного объекта в качестве инициализации, который изменяется и затем передается каждому вызову события.Событие создаст и отправит копию указателя на объект EventArgs при его возникновении.В конце концов, Event Args является объявлением ByVal.В стандартном поведении создается объект EventArgs, который используется, а затем удаляется.В этой ситуации в течение нескольких циклов в памяти фактически имеется 2 ссылки на объект EventArgs.Тяжелый вес различных свойств сохраняется последовательно, в отличие от того времени, которое необходимо для использования.Это также может привести к изменению экземпляра eventargs вызывающим кодом до того, как его сможет использовать обработчик событий.

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

Первый - плохой совет, но выполнимый.Если вы проверяете в обработчике событий, что объект события НИЧЕГО перед использованием, то вы можете вызвать событие, если аргументы событий ничего не значат.Но это плохая дизайнерская парадигма, так как она неожиданная.Мы предполагаем, что объект EventArgs будет чем-то.

Private Sub _station_BomNotLoaded(sender As Object, e As StatusEventArgs) Handles _station.BomNotLoaded
   If e IsNot Nothing Then 
      SetStatus(e)
      _alert.InvalidScan()
   End If 
End Sub

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

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

Если у вас есть добавление события, такого как «BomNotScanned», с которым не связан класс аргумента «Событие», то вы можете вызвать это событие и все, что с ним обрабатывается для конкретного сценария SKU / UPC.не сканируется.Тогда у вас все еще может быть BomNotLoaded для других сценариев, где данные не соответствуют ожидаемым.

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

Другая возможность - генерировать исключения в тех случаях, когда данные не соответствуют ожидаемым (например, SKU / UPC не сканируется), и использовать события только в тех случаях, когда данные «хороши».В этом сценарии код использования обрабатывает его как встроенный в функции, а не как событие, которое появляется в другом месте.Это имеет недостаток в том, что исключения включают информацию о стеке и могут быть более тяжелыми по сравнению с производительностью, чем события.

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

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

ИМО, у вас должен быть свой UI-флаг, эти цвета основаны на идентификационном флаге (т. Е. 2 ​​дает красный фон, с белым текстом, который выделен жирным шрифтом, в то время как 1 показывает черный текст в обычном весе на белом фоне, так далее).Это создает разделение проблем и не позволяет классу сканера диктовать, как основная форма реагирует на вещи.

Аналогично, удаление строки описания вместо определенного флага перечисления означает, что вы передаете меньше информации назад и вперед, что повышает эффективность.Это означает, что вместо отправки 3 целых чисел и строки из класса в форму вы отправляете только одно целое число.

Наконец, вы можете создать свой НОВЫЙ метод для StatusEventArgs, чтобы он не принимал параметры и просто определял определенное базовое состояние (скажем, Хорошее состояние).Затем вы можете использовать WITH (как инициализатор объекта), чтобы установить только те параметры, которые вам нужны для любого данного сценария.

Например, рассмотрим определение этого класса:

Public class StatusEventArgs
   Inherits EventArgs 

   Public Sub New()
     Flag = 1 
     Random1 = "Random Text" 
     Random2 = ""
   End Sub 

   Public Property Flag AS Integer 
   Public Property Random1 As String
   Public Property Random2 As String 
End Class

Затем я могу создать его экземпляр следующим образом:

Dim se1 As new StatusEventArgs With {.Flag = 2, .Random1="Bob Denver"} 
Dim se2 As New StatusEventArgs With {.Random1 = "Hello", .Random2="World" }

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

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

...