Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to call EndInvoke after a timeout?

On a web page, I am calling a third party who does not allow me to set timeout programatically. I call BeginInvoke and use the AsyncWaitHandle.WaitOne to wait a specified amount of time.

If the call times out, I move on and forget about the thread call I began. My question is, do I still have to call EndInvoke somehow in a timeout situation? The "CAUTION" remark on this MSDN page makes me wonder if I should: http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.71).aspx

If you believe I should, then the next question is if my web page is done processing and returns to the client before the third party comes back, would the callback method even be there listening to run the code? Doesn't the server stop looking for activitiy once my request/response is done?

Here's the code I'm using:

public class RemotePaymentProcessor
{
    private delegate string SendProcessPaymentDelegate(string creditCardNumber);

    private string SendProcessPayment(string creditCardNumber)
    {
        string response = string.Empty;
        // call web service
        SlowResponseService.SlowResponseService srs = new WebServiceTimeout.SlowResponseService.SlowResponseService();
        response = srs.GetSlowResponse(creditCardNumber);
        return response;
    }

    public string ProcessPayment(string creditCardNumber, int timeoutMilliseconds)
    {
        string response = string.Empty;

        SendProcessPaymentDelegate sppd = new SendProcessPaymentDelegate(SendProcessPayment);
        IAsyncResult ar = sppd.BeginInvoke(creditCardNumber, null, new object());
        if (!ar.AsyncWaitHandle.WaitOne(timeoutMilliseconds, false))
        {
            // Async call did not return before timeout
            response = "TIMEOUT";
        }
        else
        {
            // Async call has returned - get response
            response = sppd.EndInvoke(ar);
        }
        return response;
    }
}
like image 217
Chad Avatar asked Feb 17 '09 17:02

Chad


1 Answers

It's possible that if you don't call EndInvoke, you'll leak some resource (allocated by BeginInvoke).

So to be totally safe, always call EndInvoke() (which will block, so do it on some background thread you don't need, or switch to passing a callback so as not to burn a thread while waiting).

In practice I don't know how often it matters (I think many AsyncResults will not leak, so you may get lucky and be safe in this instance).

All of this has almost nothing to do with request-response and web servers and whatnot, this is just how the Begin/End programming model works, regardless of what application you're using it in.

like image 108
Brian Avatar answered Oct 21 '22 17:10

Brian