2016-08-23 2 views
5

Я использую окна.Должен ли я отказаться от подписки на события кнопки после использования в C#?

Приложение My C# содержит 100 user controls. Я показываю/скрываю один из тех 100 user controls в то время, когда мне нужно и скрыть все остальное. Каждый из тех, кто user controls имеет 30 buttons и подписаться на button событие следующим образом в конструкторе:

public UserControl1() 
    { 
     InitializeComponent(); 


      button1.Click += new EventHandler(MyButtonClick); 
      button2.Click += new EventHandler(MyButtonClick); 
      . 

      . 
      button30.Click += new EventHandler(MyButtonClick); 



    } 

    void MyButtonClick(object sender, EventArgs e) 
    { 
     // do something 
    } 

Так что, когда я запустить приложение все 100 User controls Подписка на 30 buttons события и некоторые user controls ПОДПИСАТЬСЯ к событию, но они никогда не используются во время использования приложения.

Я прочитал что-то о отписавшихся событиях и Here, но некоторые ответы говорят, что вы должны отказаться от подписки, потому что это вызывает утечку памяти, а некоторые говорят, что вам этого не нужно, поэтому ответ по-прежнему не ясен.

Мой вопрос: я должен отписаться от button событий после его использования, например: когда я показываю/скрываю user control. Если да, то как я могу подписаться на событие button, когда отображается user control и отписывается, когда он не отображается.

+0

Не существует ли события show/hide, которое вы могли бы использовать для прикрепления/отсоединения обработчиков событий соответственно? – PeteGO

+0

@PeteGO Я посмотрел сейчас, и я не нашел показанное даже – Kate

+0

. Есть событие IsVisibleChanged, которое вы могли бы использовать. – PeteGO

ответ

8

Почему не подписаться?

Это зависит от срока службы подписчика (UserControl) по сравнению с подпиской (Button). Подписка подписывается ссылкой на абонента. Поэтому, если подписка имеет более продолжительный срок службы, тогда абонент будет утечка памяти подписчиком.

Итак, в вашем случае вы должны спросить, сохраняются ли кнопки дольше, чем UserControl. Если кнопки имеют меньшую продолжительность при одинаковой продолжительности жизни, тогда не нужно отказаться от подписки. В противном случае произойдет утечка памяти в UserControl.

В вашем случае я предполагаю, что вам не нужно отписываться.

+0

Хорошее объяснение, но то, что я до сих пор не понимаю, - это то, как я могу узнать, продлевает ли срок подписки (кнопка), а затем абонент (userControl)? , Я не распоряжаюсь пользователем Control, и все кнопки все еще живут там, кто живет дольше, чем кто? – Kate

+0

Хорошо, если элемент управления содержит кнопки, в том случае, когда я хочу, они имеют одинаковую продолжительность жизни, и вам не нужно отказаться от подписки. –

-1

Вы не действительно должны до отказаться от подписки, но вам необходимо. Способ отказаться от подписки будет:

//adding 
EventHandler myHandler = new EventHandler(MyButtonClick); 
button1.Click += myHandler; 

//removing 
button1.Click -= myHandler; 
1

Если бы я получил свой вопрос права - каждый элемент управления подписку только на IT собственных детей (30 кнопок). Случай, когда забывают отказаться от подписки, - это плохая идея, когда издатель (кнопка) будет жить дольше, чем абонент (пользовательский контроль). Зачем? Поскольку издатель будет хранить ссылку на абонента и будет препятствовать тому, чтобы этот абонент был удален Мусороуборочным комбайном. В вашем случае кнопка никогда не будет жить дольше, чем ее родительский - пользовательский контроль, поэтому вам не нужно отписываться.

1

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

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

Теперь, когда эти недолговечные объекты выходят из сферы действия, они все равно будут прикрепляться к событию, поэтому Garbage Collector не вернет их, если долгоживущий объект (к событию которого они подписаны) находится в объем. Это связано с тем, что он сохраняет свои ссылки на объекты, которые должны обрабатывать свои события.

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

1

В вашем случае нет причин беспокоиться. Два примера, с которыми вы связаны, имеют различный «вид» события, например: если изменяется объект A, тогда должен быть вызван метод X, поэтому X может действовать или обрабатывать изменение объекта A. Например A = инвентарь продукта; если счетчик А обращается в ноль, то он больше не может быть продан или необходимо заказать новые предметы и т. д.

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

Однако в сценарии пользовательского интерфейса, таком как ваш, необходимость вызова X обычно остается. При необходимости его можно контролировать по-другому, например. отключив кнопку или скрыв ее. На самом деле нет ничего дорогого в том, что у вас есть связь между кнопкой и методом. Единственная причина для разрыва ссылки: «Я больше не хочу, чтобы X назывался EVER, если кнопка нажата».

Смежные вопросы