Often I find myself writing code like this:
if (Session != null)
{
Session.KillAllProcesses();
Session.AllUnitsReady
The event-handling pattern that's automatically generated using the vb.net WithEvents keyword is a pretty decent one. The VB code (roughly):
WithEvents myPort As SerialPort Sub GotData(Sender As Object, e as DataReceivedEventArgs) Handles myPort.DataReceived Sub SawPinChange(Sender As Object, e as PinChangedEventArgs) Handles myPort.PinChanged
will get translated into the equivalent of:
SerialPort _myPort;
SerialPort myPort
{ get { return _myPort; }
set {
if (_myPort != null)
{
_myPort.DataReceived -= GotData;
_myPort.PinChanged -= SawPinChange;
}
_myPort = value;
if (_myPort != null)
{
_myPort.DataReceived += GotData;
_myPort.PinChanged += SawPinChange;
}
}
}
This is a reasonable pattern to follow; if you use this pattern, then in Dispose you would set to null all properties that have associated events, which will in turn take care of unsubscribing them.
If one wanted to automate disposal slightly, so as to ensure that things got disposed, one could change the property to look like this:
ActionmyCleanups; // Just once for the whole class SerialPort _myPort; static void cancel_myPort(myType x) {x.myPort = null;} SerialPort myPort { get { return _myPort; } set { if (_myPort != null) { _myPort.DataReceived -= GotData; _myPort.PinChanged -= SawPinChange; myCleanups -= cancel_myPort; } _myPort = value; if (_myPort != null) { myCleanups += cancel_myPort; _myPort.DataReceived += GotData; _myPort.PinChanged += SawPinChange; } } } // Later on, in Dispose... myCleanups(this); // Perform enqueued cleanups
Note that hooking static delegates to myCleanups means that even if there are many instances of myClass, there will only have to be one copy of each delegate system-wide. Perhaps not a big deal for classes with few instances, but potentially significant if a class will be instantiated many thousands of times.