Why is this an issue?
Calling the BeginInvoke
method of a delegate will allocate some resources that are only freed-up when EndInvoke
is
called. This is why you should always pair BeginInvoke
with an EndInvoke
to complete your asynchronous call.
This rule raises an issue when:
- the
BeginInvoke
method is called without any callback and it is not paired with a call to EndInvoke
in the same
block.
- a callback with a single parameter of type
IAsyncResult
doesn’t contain a call to EndInvoke
.
Noncompliant code example
BeginInvoke without callback
Public Delegate Function AsyncMethodCaller() As String
Public Class Sample
Public Sub DoSomething()
Dim Example As New AsyncExample()
Dim Caller As New AsyncMethodCaller(Example.SomeMethod)
' Initiate the asynchronous call.
Dim Result As IAsyncResult = Caller.BeginInvoke(Nothing, Nothing) ' Noncompliant - Not paired With EndInvoke
End Sub
End Class
BeginInvoke with callback
Public Delegate Function AsyncMethodCaller() As String
Public Class Sample
Public Sub DoSomething()
Dim Example As New AsyncExample()
Dim Caller As New AsyncMethodCaller(Example.SomeMethod)
' Initiate the asynchronous call.
Dim Result As IAsyncResult = Caller.BeginInvoke(New AsyncCallback(Sub(ar)
End Sub), Nothing) ' Noncompliant - Not paired With EndInvoke
End Sub
End Class
Compliant solution
BeginInvoke without callback
Public Delegate Function AsyncMethodCaller() As String
Public Class Sample
Public Function DoSomething() As String
Dim Example As New AsyncExample()
Dim Caller As New AsyncMethodCaller(Example.SomeMethod)
' Initiate the asynchronous call.
Dim Result As IAsyncResult = Caller.BeginInvoke(Nothing, Nothing)
' ...
Return Caller.EndInvoke(Result)
End Function
End Class
BeginInvoke with callback
Public Delegate Function AsyncMethodCaller() As String
Public Class Sample
Public Sub DoSomething()
Dim Example As New AsyncExample()
Dim Caller As New AsyncMethodCaller(Example.SomeMethod)
' Initiate the asynchronous call.
Dim Result As IAsyncResult = Caller.BeginInvoke(New AsyncCallback(Sub(ar)
' Call EndInvoke to retrieve the results.
Dim Ret As String = Caller.EndInvoke(ar)
' ...
End Sub), Nothing)
End Sub
End Class
Resources
Calling
Synchronous Methods Asynchronously