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 string AsyncMethodCaller();
public static void Main()
{
AsyncExample asyncExample = new AsyncExample();
AsyncMethodCaller caller = new AsyncMethodCaller(asyncExample.MyMethod);
// Initiate the asynchronous call.
IAsyncResult result = caller.BeginInvoke(null, null); // Noncompliant - not paired with EndInvoke
}
BeginInvoke with callback
public delegate string AsyncMethodCaller();
public static void Main()
{
AsyncExample asyncExample = new AsyncExample();
AsyncMethodCaller caller = new AsyncMethodCaller(asyncExample.MyMethod);
IAsyncResult result = caller.BeginInvoke(
new AsyncCallback((IAsyncResult ar) => {}),
null); // Noncompliant - not paired with EndInvoke
}
Compliant solution
BeginInvoke without callback
public delegate string AsyncMethodCaller();
public static void Main()
{
AsyncExample asyncExample = new AsyncExample();
AsyncMethodCaller caller = new AsyncMethodCaller(asyncExample.MyMethod);
IAsyncResult result = caller.BeginInvoke(null, null);
string returnValue = caller.EndInvoke(result);
}
BeginInvoke with callback
public delegate string AsyncMethodCaller();
public static void Main()
{
AsyncExample asyncExample = new AsyncExample();
AsyncMethodCaller caller = new AsyncMethodCaller(asyncExample.MyMethod);
IAsyncResult result = caller.BeginInvoke(
new AsyncCallback((IAsyncResult ar) =>
{
// Call EndInvoke to retrieve the results.
string returnValue = caller.EndInvoke(ar);
}), null);
}
Resources
Calling
Synchronous Methods Asynchronously