When and where to call the RemoveHandler in VB.NET

2019-08-04 21:34发布

I am working to a VB.NET windows forms projet in .NET 1.1. And I have this type of architecture, very simplified.

Public MustInherit Class BaseTestLogic

  Private _TimerPoll As Timer

  Public Sub New(ByVal sym As SymbolFileMng, ByVal cfg As LampTestConfig, ByVal daas As DaasManager, ByVal mcf As Elux.Wg.Lpd.MCFs.VMCF)

    AddHandler _TimerPoll.Tick, AddressOf TimerPoll_Tick

  End Sub

End Class

Public Class SpecificTestLogic
  Inherits BaseTestLogic      

End Class

Depending of the type of test I am doing I create an instance of a specific test derived from BaseTestLogic. But I found that after hundreds of object creations I can have StackOverflow exception.

I checked my code and saw that I forgot to remove the handler to Timer Tick. The question is, where and when is it correct to remove hadler?

Do I need to implement the IDisposable interface in the base class and RemoveHandler in Dispose?

5条回答
做个烂人
2楼-- · 2019-08-04 22:07

My first thought is that your actual problem has little, if anything, to do with adding and removing event handlers. A StackOverflowException means you have a series of functions that are creating an infinite loop of recursive calls. The code you posted does not show anywhere that could happen, but the stack trace of the exception should point you to the offending code.

Based on your comment about creating a test of a derived type, I wonder if you could post more of the code from the constructor in your base class.

查看更多
神经病院院长
3楼-- · 2019-08-04 22:14

You may go along with removing the handler when the Dispose is called, but a purist would say that "you shouldn't abuse IDisposable for purposes other than disposing unmanaged resources".

Another option is to remove the handler at the Finalize method.

You can also feel comfortable about removing the handler at several different places, if that makes any sense in your design. Removing an already removed handler will not cause any issue - unless the event is a Custom Event and its AddHandler/RemoveHandler implementations don't match the behavior of non-custom events (which is simply to use [Delegate].CombineDelegate/[Delegate].Remove). Just don't tell your purist friends about it; they won't comply.

查看更多
Animai°情兽
4楼-- · 2019-08-04 22:21

It is strange but in my case the finalizer is never called, what could be the reason?

Or GC.SupressFinalize() has been called somewhere in your code?

查看更多
兄弟一词,经得起流年.
5楼-- · 2019-08-04 22:26

If you add them in the constructor it would feel right to remove them in the Dispose, but it of course depends on your design.

Here is a question with information about when you need to worry about removing them
AddHandler/RemoveHandler Not Disposing Correctly

查看更多
三岁会撩人
6楼-- · 2019-08-04 22:33

This is an old question but I came to it via web search so it is still a useful question about Timers. No appropriate answer was given to your UNDERLYING problem. Answers were offered to your question, but the question was wrong. Your question should be: How do I disable a timer so the event no longer fires?

Dim WithEvents timer1 as new Timer()

(then add timer1_Elapsed to your code)

This solves the problem of worrying about IDisposable or Finalize because the Timer event handler is managed for you. When you no longer need the timer, set Enabled = False or call the Stop() method to keep it from ticking.

查看更多
登录 后发表回答