How to set IHttpAsyncHandler a timeout?
Asked Answered
P

3

9

I've tried to set the executionTimeout in the web.config file:

<compilation debug="false" targetFramework="4.5">
<httpRuntime executionTimeout="30"/>

Looking at the IIS Manager Requests page I can see the requests are not being terminated after 30 seconds.
Should I implement a Timer inside my IHttpAsyncHandler?

Pridemore answered 22/5, 2012 at 21:0 Comment(2)
I would recommend instead figuring out why your code is running longer than you would like, and having periodic checks within it to stop execution and return what it has so far, if possible.Footstall
@andrew-barber I'm using IHttpAsyncHandler for long pooling(in order to psuh notification to the client). It's supposed to have long running times, but still I would like to have a timeout.Pridemore
R
6

With the apparent lack of built-in support for IHttpAsyncHandler timeouts, presumably you must manage your own timeout. Perhaps this is by design; after all you are choosing an asynchronous pattern - who does MSFT think they are trying to set a default timeout for your long running task?

What I would do is use ThreadPool.RegisterWaitForSingleObject to manage your polling with an appropriate timeout. Here is a code sample I use to avoid waiting on a web service that never returns:

private const int REQUEST_TIMEOUT = 30000;   // miliseconds (30 sec)
private void CallService()
        {
        try {
             string url = "somewebservice.com";
             WebRequest request = WebRequest.Create(url);

             // Asynchronously fire off the request
             IAsyncResult result = request.BeginGetResponse(new AsyncCallback(MyRoutineThatUsesTheResults), request);

             // Handle timed-out requests
             ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(RequestTimeout), request, REQUEST_TIMEOUT, true);
         }
         catch (Exception ex) {
              _logger.Error("Error during web service request.", ex);
         }

private void RequestTimeout(object state, bool timedOut)
        {
            if (timedOut) {
                WebRequest request = (WebRequest)state;
                _logger.WarnFormat("Request to {0} timed out (> {1} sec)", request.RequestUri.ToString(), REQUEST_TIMEOUT / 1000);
                request.Abort();
            }
        }

You will need an IAsyncResult to work with this approach but that's an established pattern you shouldn't have trouble running down samples about.

Also, you will run into issues when IIS decides to recycle your app pool / tear down your app domain while your polling is still running. If that's a condition you want to handle, you can use HostingEnvironment.RegisterObject.

Rowden answered 31/5, 2012 at 21:16 Comment(0)
T
-1

You can try to add this to your web.config file:

<system.web>
  <pages asyncTimeout="30" />
</system.web>

Its for PageAsyncTask, but just might be honored for IHttpAsyncHandler too?

If not, you may have more luck with the new HttpTaskAsyncHandler in ASP.Net 4.5 version: http://www.asp.net/vnext/overview/whitepapers/whats-new#_Toc318097378

Toothache answered 29/5, 2012 at 2:48 Comment(2)
Seems to have no effect on the handlerPridemore
This does not work.Gil
B
-1

You would have to use RegisterAsyncTask check the link below

http://msdn.microsoft.com/en-us/magazine/cc163725.aspx

Berley answered 29/5, 2012 at 11:42 Comment(1)
PageAsyncTask can not be used in IHttpHandler nor IHttpAsyncHandlerUnlettered

© 2022 - 2024 — McMap. All rights reserved.