Implementing IDisposable on a simple class - vb.net

I wanted to make a helper class for my MySql wrapper. The idea is that the methods that encapsulate mysql command construction and execution have an optional MySqlConnection as an argument. If a specific connection is passed, it uses that, if not, it creates one and disposes of it once done. To save 4 lines off every method, I could use this class in the using block and pass the optional argument as a construction parameter. Anyway, heres the class:
Public Class DynaConnection
Implements IDisposable
Public Dynamic As Boolean
Public Connection As MySqlConnection
Public Sub New(Connection As MySqlConnection)
If Connection Is Nothing Then
Dynamic = True
Me.Connection = Connect()
Else
Dynamic = False
End If
End Sub
Public Shared Widening Operator CType(ByVal Connection As DynaConnection) As MySqlConnection
Return Connection.Connection
End Operator
Public Sub Dispose() Implements IDisposable.Dispose
If Dynamic Then
Connection.Close()
Connection.Dispose()
End If
GC.SuppressFinalize(Me)
End Sub
End Class
When I first wrote the letters "Implements IDisposable" though, a whole wall of code jumped into the class. I looked at msdn to see whats what but over there was an even longer bunch of code on how to "properly" implement IDisposable.
From what I remember from writing simple IDisposable classes before, what I've done in the class above should suffice. Has something changed?

This is that "wall of code" with some additional comments.
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
'If your class holds references to other .NET objects
'that themselves implement IDisposable then you should implement IDisposable
'and call their Dispose method in yours
End If
' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
'If you're holding any OS resources, e.g. file or image handles,
'then you should release them. That will be a rare thing for most people and can be pretty much ignored
' TODO: set large fields to null.
'If any of your fields may refer to objects that occupy
'a large amount of memory then those fields should be set to Nothing
End If
Me.disposedValue = True
End Sub
' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
I agree with GSeng, this is the correct way to implement IDisposable.

Related

Can you get/change data of ALL instances of an object from within a shared function within a class?

Problem:
I have a class where I have a eventlog that logs for that particular instance of the class and logs to a shared eventlog and to track changes across all instances.
My issue is that I want the logs to be re sizable in their number of entries and I need to make sure that the shared log is never smaller than any of the instanced logs. Is it possible to check this?
What I've tried:
I've seen a-lot about GetType and reflections and I've been able to get instance names but I can't figure out how to reference data within those instances.
Below is a psuedocode of where I am at.
Public Class Test
Public InstancedLog As DataSet
Public Shared SharedLog As DataSet
Public Shared Sub ResizeSharedLog(ByRef DesiredSize As Integer)
If DesiredSize < ("check and sum up the size of all instances of InstancedLog") Then
'can't resize, too small.
Else
'resize to DesiredSize.
End If
End Sub
End Class
Any help would be much appreciated.
Here's an example of a class that tracks its own instances:
Public Class Class1
Implements IDisposable
Private Shared instances As New List(Of Class1)
Public Sub New()
instances.Add(Me)
End Sub
Public Shared Sub TouchEveryInstance()
For Each instance As Class1 In instances
'Use instance here.
Next
End Sub
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
instances.Remove(Me)
End If
' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
' TODO: set large fields to null.
End If
disposedValue = True
End Sub
' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
Dispose(True)
' TODO: uncomment the following line if Finalize() is overridden above.
' GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
Most of that code is auto-generated by VS when you add the Implements IDisposable line. The entire region was added automatically except the line that refers to the instances field. I added the instances field, the constructor and the TouchEveryInstance method.

How to find the window MS Word in order to sub-class and override WndProc

I need to use custom event processing for ebedded Office applications in a WebBrowser ActiveX control. I have made great progress using the WebBrowser as a container for Word, Excel and PowerPoint and so far with some work I'm able to get almost all the behavior I require. However, the one thing I need to be able to do is to detect mouse clicks in a document and differentiate those that are on hyperlinks from those that are not.
I've been able to get close to a solution using a global hook but the process/logic I use for Word doesn't work for Excel.
In any case, after reading this I decided overriding WndProc might be a better approach. Using the following code I put together a NativeWindow sub-class and an override for the WndProc. Unfortunately, it is never called so I assume I'm not using the correct window handle to instantiate it.
I use the class like this:
wordDocument.Application.ActiveDocument.ActiveWindow.SetFocus()
hWndOffice = GetFocus()
officeWindow = New OfficeWindow(hWndOffice)
I'm using VB .NET but not VSTO...
Any ideas how to get the correct window handle?
Friend Class OfficeWindow
Inherits NativeWindow
Implements IDisposable
Public Sub New(handle As IntPtr)
Me.AssignHandle(handle)
End Sub
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Console.WriteLine(m.Msg)
Select Case m.Msg
Case &H200
Console.WriteLine("WM_MOUSEMOVE")
End Select
MyBase.WndProc(m)
End Sub
' Flag: Has Dispose already been called?
Dim disposed As Boolean = False
' Public implementation of Dispose pattern callable by consumers.
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
' Protected implementation of Dispose pattern.
Protected Overridable Sub Dispose(disposing As Boolean)
If disposed Then Return
If disposing Then
' Free any other managed objects here.
'
Me.DestroyHandle()
End If
' Free any unmanaged objects here.
'
disposed = True
End Sub
Protected Overrides Sub Finalize()
Dispose(False)
End Sub
End Class

Finalize not called for publically declared class

I have a class that I need in many forms, so I have declared it in a module.
Module modTTS
Public g_TTS As clsTTS
End Module
I have a Finalize method in this class:
Protected Overrides Sub Finalize()
Stop'this is never called. I don't know why
MyBase.Finalize()
End Sub
I do not explicitely destroy the class when my program ends.
I just wanted to silently let it slip out of scope.
Is that not valid? What might be the reason why the Finalize procedure is not called?
Thank you!
According to the suggestions, I have changed my class to this:
Public Class clsTTS : Implements IDisposable
Private _Synth As New SpeechSynthesizer
Private _bDisposed As Boolean = False
' Public implementation of Dispose pattern callable by consumers.
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
' Protected implementation of Dispose pattern.
Protected Overridable Sub Dispose(ByVal uDisposing As Boolean)
If _bDisposed Then
Return
End If
If uDisposing Then
' Free any other managed objects here.
If Not _Synth Is Nothing Then
_Synth.Dispose()
End If
End If
' Free any unmanaged objects here.
_bDisposed = True
End Sub
here's an example using the ApplicationContext Class - MSDN
also, Finalize() might not be called before the application thread terminates, therefore, resources are never released.
You should implement the IDisposable Interface - MSDN instead. and call .Dispose() method of your object on ApplicationExit.
iDisposable is simple to implement, just add : Implements iDisposable to your Class declaration, and intellisense will add the necessary procedures.
You can also dispose of /close objects in a FormClosing / FormClosed event.
personally, i only use Shared members as functions, or to keep some string vars, but not objects.
Take a look at the following link to learn how to do unintialization of static members:
http://bytes.com/topic/c-sharp/answers/536465-there-anything-like-static-destructor
How to get notified before static variables are finalized

VB.NET Do I need to close filestream at class finalize?

I have a class in which I have declared a FileStream and a StreamReader:
Option Strict Off
Option Explicit On
Friend Class clsFileReader
Private _fs As IO.FileStream
Private _sr As IO.StreamReader
I would like ask if I explicitely need to close these like this:
Protected Overrides Sub Finalize()
_fs.Close()
_sr.Close()
End Sub
... or if that is done automatically.
Thank you for the help!
ps: I can not use "using" because I want to read the file line by line like this:
Public Function ReadLine() As String
Debug.Assert(Not _sr.EndOfStream)
_sCurrentLineString = _sr.ReadLine
_iCurentLineIndex = _iCurentLineIndex + 1
Return _sCurrentLineString
End Function
I would suggest you use the same fonctionality as found in the stream. Implement the IDisposable interface and call .Dispose on your class instance when you're done with it. Same as you would do with a stream.
Here's a quick example.
Class clsFileReader : Implements IDisposable
Private _fs As IO.FileStream
Private _sr As IO.StreamReader
' Flag: Has Dispose already been called?
Dim disposed As Boolean = False
' Public implementation of Dispose pattern callable by consumers.
Public Sub Dispose() _
Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
' Protected implementation of Dispose pattern.
Protected Overridable Sub Dispose(disposing As Boolean)
If disposed Then Return
If disposing Then
' Free any other managed objects here.
'
_fs.Close()
_sr.Close()
End If
' Free any unmanaged objects here.
'
disposed = True
End Sub
Protected Overrides Sub Finalize()
Dispose(False)
End Sub
End Class

VB.net: Custom ' TODO: List on an Interface

How do I add my own todo and comments list to appear on Interfaces? I want it to pop up like IDisposable does:
Public Class Foo : Implements IDisposable
Private disposedValue As Boolean = False ''# To detect redundant calls
''# IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
''# TODO: free other state (managed objects).
End If
''# TODO: free your own state (unmanaged objects).
''# TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
''# This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
''# Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
Whenever I enter my own comments and todo list they are never autogenerated like IDisposable Interface does. I would like my own Interfaces to preserve the comments so that I can share my Interfaces with in source documentation.
This code is hard-baked into Common7\IDE\msvb7.dll. Pretty shocking, considering how totally inappropriate it is for the 99.99% of cases where you'd want to implement IDisposable.
Consider using code snippets. You can create your own snippets with the Snippet Editor.