Re: When to use IDisposable?
Your dispose sub includes you disposing wc, but you already disposed it in your using statement in the New sub.
Edit: Now I see your question #3. Yes, that object will be disposed after it adds that handler.
Re: When to use IDisposable?
In truth, there really are only unmanaged resources. A managed resource is just a managed object that itself holds unmanaged resources, or holds a reference to another managed resource. If you have a managed object that has a reference to a managed object that has a reference to a managed object that holds an unmanaged resource then there's really only one resource, but all the managed objects are considered managed resources. Any and every managed resource must have a Dispose method. If a class has a Dispose method then it's a managed resource. If a class holds managed or unmanaged resources then it MUST have a Dispose method.
So, it's going to be relatively rare that your managed objects hold unmaanged resources directly, although it will happen sometimes. More likely is that you will have a reference to a managed resource, which is an indirect reference to an unmanaged resource.
Implementing the IDisposable interface is easy. You simply type "implements idisposable" under your class declaration and hit Enter:
vb.net Code:
Public Class NoGateway
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
You then simply replace the three TODOs with the appropriate code. If you have no managed resources then you can remove the first TODO, and therefore the If block too. If you have no unamanged resources you can remove the second TODO. If you have no large fields then you can remove the third TODO.
In your case you would replace the first TODO with your RemoveHandler and webClient.Dispose code. The second TODO would go and you could set your WebClient field to Nothing in place of the third if you wanted.
You are incorrectly using the Using statement in that code. The point of the Using block is to create an object that will be used only within that block and disposed at the End Using statement. Obviously that's not what you want.
Re: When to use IDisposable?
Hello,
Sorry to be a pain, just a few questions about your comments.
I have made the adjustments to my code. I know VB does this, but I would like to do it myself, for my own understanding.
vb Code:
Public Class NoGateway
Implements IDisposable
Private wc As WebClient = Nothing
Public Sub New()
wc = New WebClient()
AddHandler wc.DownloadStringCompleted, AddressOf wc_DownloadStringCompleted
End Sub
' Start the Async call to find if NoGateway is true or false
Public Sub NoGatewayStatus()
' Start the Async's download
wc.DownloadStringAsync(New Uri([url]www.xxxx.xxx[/url]))
' Do other work here
End Sub
Private Sub wc_DownloadStringCompleted(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
' Do work here
End Sub
' Dispose of the NoGateway object
Public Sub Dispose()
RemoveHandler wc.DownloadStringCompleted, AddressOf wc_DownloadStringCompleted
wc.Dispose()
wc = Nothing
End Sub
End Class
As I am not using any unmanaged resources I have removed the if statement and the boolean, and also the GC.SuppreseFinalizer() as I don't have a finalizer that the GC will call.
So when the client of this class it using it I could do 2 things that will call the Dispose()
1)
objNoGateway = new NoGateway()
Using objNoGateway
' Use the object and when it reaches the end of the using statement it will automatically call the Dispose method
End Using
2) Manually dispose of the object
objNoGateway = new NoGateway()
' use the object and when finished call the dispose method
objNoGateway.Dispose()
As my NoGateway wraps the WebClient class. I don't need to dispose of my NoGateway class as that is handled by the framework?
Many thanks,
Re: When to use IDisposable?
You should absolutely NOT write out all the code yourself because you're actually making it harder to understand. Have you tried to compile that code? It will refuse and it will tell you that your class has no implementation for the IDisposable.Dispose method. That's because you have failed to add the Implements clause to your Dispose method, which the IDE would have done for you.
Your code could also cause run time errors that would be hard to diagnose. Take a look at the code that the IDE generates. Notice that there are two Dispose methods? It does that for a reason. You say:
Quote:
As I am not using any unmanaged resources I have removed the if statement and the boolean
but that is the exact opposite of what you should be doing. The If statement and the Boolean filed exist SPECIFICALLY for managed resources. If you go back and read my post again I said:
Quote:
If you have no managed resources then you can remove the first TODO, and therefore the If block too.
This is all done for a reason and it's explained in the documentation but here goes anyway. If an instance of your class is created and assigned to a variable and then that variable loses scope before the object is disposed, it's going to be left up to the GC to dispose your object when it finalises it. At that point your Dispose method will be called and it will try to dispose the WebClient. Who's to say that the GC hasn't already cleaned up that WebClient object though? If it has then you'll get an exception thrown for trying to access invalid memory. That's why you MUST NEVER release managed resources unless the object is being explicitly disposed, which is why you need two Dispose methods.
Just let the IDE implement the IDisposable interface for you and then follow the instructions it provides in the generated code. If you do that you know that it's done properly.