You need to call EndInvoke (or define a callback) for asynchronous method calls, even if you have nothing to do when it returns

I found the following code snippet in CodeProject when calling methods asynchronously ... http://www.codeproject.com/Articles/14931/Asynchronous-Method-Invocation

private void CallFooWithOutAndRefParameters() { // create the paramets to pass to the function string strParam1 = "Param1"; int intValue = 100; ArrayList list = new ArrayList(); list.Add("Item1"); // create the delegate DelegateWithOutAndRefParameters delFoo = new DelegateWithOutAndRefParameters(FooWithOutAndRefParameters); // call the beginInvoke function! IAsyncResult tag = delFoo.BeginInvoke(strParam1, out intValue, ref list, null, null); // normally control is returned right away, // so you can do other work here... // calling end invoke notice that intValue and list are passed // as arguments because they might be updated within the function. string strResult = delFoo.EndInvoke(out intValue, ref list, tag); // write down the parameters: Trace.WriteLine("param1: " + strParam1); Trace.WriteLine("param2: " + intValue); Trace.WriteLine("ArrayList count: " + list.Count); Trace.WriteLine("return value: " + strResult); } 

There are a few things that I don’t understand about this code.

The call code is immediately returned to the comment control when it hits the BeginInvoke line.

Does this mean that the following code (EndInvoke, followed by some trace tracking) only works after the call to FooWithOutAndRefParameters completes ... automatically (although this code is in the same method). It bothers me a bit. (I always used callbacks for this kind of thing.)

Using this method, I have to call EndInvoke. Can I just call the method asynchronously and forget that this happened? Any flaws in this?

If I do not call EndInvoke (as shown in this method), should I always have a callback? Even if the callback does nothing.

If the answers YOU MUST ... then you call EndInvoke OR define a callback? (The advantage of defining a callback is that you received a notification of the result)

By the way. I know that I can check for errors or logical results in an EndInvoke or callback (and actually I could do that). I was wondering if there are RISKS due to the lack of an EndInvoke call or the definition of a callback (e.g. memory leak)? What is the best practice.

Set

+4
source share
3 answers

Yes, you need to call EndInvoke (). This does not lead to a rather unpleasant drain of resources, which lasts 10 minutes. The underlying plumbing is .NET Remoting, 10 minutes is, um, "default rental time." Do this often enough, and your program will boil. Having a delegate’s goal takes more than 10 minutes and has interesting results.

But most importantly, if not for the result of the called operation, you need to find out if the launched method has completed successfully. If he died on exception, you won't know about it until you call EndInvoke (). At this point, the exception is raised again. Actually handling this exception is quite difficult, since you really don't know how much of your program state was changed by the delegate’s goal before it exploded. It is very important that the target does not have too many side effects if you really want to catch it. Or vice versa, that the target catches and recreates the exception, performing state recovery if necessary.

The example you used is pretty dumb, of course, it's hard to come up with anything useful between calling BeginInvoke and EndInvoke in one way. You always rely on a callback that you can register from the second to the last argument in the BeginInvoke call. Or, in other words, don't miss null , as the sample code did. And use classes like BackgroundWorker and Task, even ThreadPool.QueueUserWorkItem () to get rid of this code. Using the BeginInvoke () method for a delegate is very low level hacking.

Delegates are an extremely powerful abstraction in .NET, but they do not spread their capabilities too well. Using them to implement events is a template and no problem. Using its BeginInvoke () method is a black belt.

+9
source

First of all, these links may be of interest:

Asynchronous call of synchronous methods

Do I need to delegate .EndInvoke ()?


Now about your questions:

The call code is immediately returned to the comment control when it falls into the BeginInvoke line.

Yes, the call is executed asynchronously (I can assume that it is using a different thread).

Does this mean that the following code (EndInvoke, followed by some trace tracking) is executed only after calling FooWithOutAndRefParameters completes ... automatically (although this code is in the same method). It bothers me a bit. (I always used callbacks for this kind of thing.)

EndInvoke blocks execution until the thread (method) initiated by BeginInvoke completes. In this context, it is similar to threading.

Using this method, I have to call EndInvoke. Can I just call the method asynchronously and forget that this happened? Any flaws in this?

You should always call EndInvoke (see below). There are probably many reasons for this, but the one that, in my opinion, is most important is that if the method fails, by throwing an exception, you will not get the exception until EndInvoke is called.

If I do not call EndInvoke (as shown in this method), then should I always have a callback? Even if the callback does nothing.

The callback should call EndInvoke in this case, from the callback. Thus, only a callback is optional.

If the answers you MUST ... then you call EndInvoke OR define a Call Back? (The advantage of defining a callback is that you are notified of the result)

You do not need to define a callback, but if you do, you call it in EndInvoke.

You better understand which scenario is better: notify, completely asynchronously, that the method is finished or forcibly connects to the method (thus blocking the calling thread). It's all about control, and you have to do one or the other, or even both.

By the way, I know that I can check for errors or logical results in EndInvoke or callback (and I could do that). I was wondering if ARE IS RISK from not calling EndInvoke or defining a callback (memory leak, for example)? What is the best practice.

Not at its core, no, I don't think there are risks. But you should always check if the method was unsuccessful or completed successfully.


From MSDN , here are options for what can be done after BeginInvoke:

  • Follow some steps and then call EndInvoke to block until the call ends.

  • Get WaitHandle using the IAsyncResult.AsyncWaitHandle property, use the WaitOne method to block execution until WaitHandle is called and then call EndInvoke.

  • Interrogate the IAsyncResult returned by BeginInvoke to determine when the asynchronous call has completed, and then call EndInvoke.

  • Pass the delegate to the callback method for BeginInvoke. This method is executed on the ThreadPool thread when the asynchronous call completes. The callback method calls EndInvoke.


OBS: As @ScottChamberlain said in the comments, MSDN states that :

You can call EndInvoke to get the return value from the delegate, if necessary, but not required. EndInvoke blocks until a return value is received.

I think the reason is that when working with Controls, you are working in a user interface thread. Since EndInvoke blocks the thread, there may be reasons why you do not want to do this. However, I would recommend using a callback or polling to complete to make sure the method completed successfully. This will make your program more reliable (or error resistant).

+5
source

Typically, you should call EndInvoke, because the caller may have handlers subscribed to events that may not matter to your processing, but may matter to the consumer, to ensure that certain types of processing may take place at a known time / state applications.

+1
source

All Articles