Do you have to call EndInvoke (or define a callback ) for asynchronous method calls even if you don't have anything to do when it returns

后端 未结 3 565
面向向阳花
面向向阳花 2020-12-06 13:08

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



        
3条回答
  •  醉梦人生
    2020-12-06 13:55

    Before anything, these links might be of interest:

    Calling Synchronous Methods Asynchronously

    Is Delegate.EndInvoke() really necessary?


    Now, about your questions:

    Per the comment control is returned immediately to the calling code when it hits the BeginInvoke line.

    Yes, the call is made asynchronously (I may assume it's using another thread).

    Does that mean that the code that follows (EndInvoke followed by some trace logging) only runs after the FooWithOutAndRefParameters call completes...automagically (even though that code resides in the same method). It looks a little confusing to me. (I have always used callbacks for this kind of thing.)

    EndInvoke will block the execution until the thread (method) initiated by the BeginInvoke finishes. In this context, it's analogous to a thread join.

    Using this method do I HAVE to call EndInvoke. Can I just invoke the method asyncronously and forget it happened? Any downsides to this?

    You must always call EndInvoke (see below). There are probably many reasons for that, but the one that I think it's the most important is that if the method failed, by throwing an exception, you won't get the exception until EndInvoke is called.

    If I don't call EndInvoke (as is shown in this method) should I then always have a callback? Even if the callback does nothing.

    The callback must call EndInvoke in that case, from the callback. So only the callback is optional.

    If the answers YOU SHOULD... then do you call EndInvoke OR define a callback? (The advantage to defining a callback being that you are notified of the result)

    You do not have to define the callback, but if you do, you call EndInvoke in it.

    It's up to you to understand which scenario is better: be notified, completely asynchronously, that the method finished or force a join with the method (thus blocking the calling thread). It's all about control, and you should do one or another, or even both.

    BTW I know I could check for errors or log resuls in the EndInvoke or callback (and I might in fact do that). What I was wondering is ARE THERE RISKS from not calling EndInvoke or defining a callback (memory leaks for example)? What is the best practice.

    Not inherently, no, I don't believe that there are risks. But you must always check if the method failed or completed successfully.


    From MSDN, here are the options of what can be done after a BeginInvoke:

    • Do some work and then call EndInvoke to block until the call completes.

    • Obtain a WaitHandle using the IAsyncResult.AsyncWaitHandle property, use its WaitOne method to block execution until the WaitHandle is signaled, and then call EndInvoke.

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

    • Pass a delegate for a callback method to BeginInvoke. The method is executed on a 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 retrieve the return value from the delegate, if neccesary, but this is not required. EndInvoke will block until the return value can be retrieved.

    I think the reason behind it that, when dealing with Controls, you are operation on the UI Thread. Since EndInvoke blocks the thread, there might be reasons for you to not want to do that. Still, I'd recommend using a callback or polling for completion in order to make sure you method has completed successfully. This would make your program more robust (or error-resilient).

提交回复
热议问题