2

I'm trying to set a near-infinite timeout value on a WebRequest, considering that the HTTP-based API which I'm querying already graciously handles timeouts by sending back an XML document that declares a timeout. For some reason though, the following code still throws an exception:

Dim request As WebRequest = WebRequest.Create("http://api/cgi-bin/do?cmd=longRunningOperation&timeout=300")
' ^ command returns timeout if not complete within 300 seconds (5 minutes)

request.Timeout = Integer.MaxValue ' so we don't need client-side timeout handling

Dim response As WebResponse = request.GetResponse() ' yet this call blows up

I'm sorry that I can't provide something that you can debug, but according to MSDN, this is how to do it. Yet I still get a WebException after about 100 seconds (message: The operation has timed out, status: WebExceptionStatus.Timeout).

Can someone explain this behaviour? (And if not, propose a workaround?)

EDIT

The problem probably has something to do with the fact that this snippet is executed in a Task, but so far that's still all I know.

EDIT2

Running the code on the UI thread still throws the same exception, so maybe that's not it after all...

EDIT3

After a good night's sleep, I think it may be doing this because I'm not properly closing my response or response streams. I'm sending multiple requests while the long-running operation is still busy. I can imagine that there is a gotcha on a lower level if you don't properly dispose here. But for me it's hard to say because I don't know the inner workings of the webrequest/webresponse classes.

The code that I'm using: http://code.google.com/p/dune-api-codepack/source/browse/ApiWrappers/DuneCommands/CommandResult.vb (not the latest commit but the differences are not too big)

The problematic method is GetResults(command). Don't mind the GetResultsAsync method, it is just a draft (although it probably contains the same error).

EDIT4

Disregard everything I've said, the problem and solution are in my answer below.

Steven Liekens
  • 13,266
  • 8
  • 59
  • 85
  • 1
    Works just fine for me. I created a fake page `LongRunning.aspx` that calls `Thread.Sleep` for an arbitrary number of seconds. When I have the page sleep for 150 seconds and no `request.Timeout`, I get the error message you refer to (since the default timeout is 100 seconds). However, when I use your code and set `request.Timeout = Integer.MaxValue`, it works just fine, completing the request after waiting 150 seconds. Can you try running with a proxy like [**Fiddler**](http://www.fiddler2.com/fiddler2/) to see if there's another reason for the connection closing further down the pipeline? – mellamokb May 14 '12 at 21:29
  • Okay I'll spin up good old wireshark. – Steven Liekens May 14 '12 at 21:32
  • There's nothing originating from the server to indicate that the request was aborted. Which is correct, it never actually aborts the operation. Not even when a command timeout (as defined by the query parameter) is reached. Yet still the `GetResponse` call throws the exception... – Steven Liekens May 14 '12 at 21:41
  • 1
    Is this actually your entire code for this process, or are there other lines of code going on in between you could provide? – mellamokb May 14 '12 at 21:47
  • 1
    I think I found out what's going on, this code is running inside a task... that can't be good. – Steven Liekens May 14 '12 at 21:51
  • Ah. Yes there could be some sort of timeout on the Task as well. – mellamokb May 14 '12 at 21:52
  • It still does this when executed on the UI thread, sadly. There's no code that could abort the request anywhere in my application, so it beats me why it won't just wait until the server returns a response (whether it be an XML doc indicating succes, failure or timeout). – Steven Liekens May 14 '12 at 22:36
  • 1
    Sorry, it's hard to say since I can't reproduce it here. I tested in LINQPad and it works just fine. Is it possible you could simplify the code to a minimum complete project/solution that demonstrates the issue that you can upload somewhere? I can easily simulate a long running page so you wouldn't need to expose your real urls. – mellamokb May 14 '12 at 23:00
  • As requested: http://dl.dropbox.com/u/14454764/MinimalProject.zip Curiously, the exception does not occur in this console application, using the exact same API call. I still can't think of anything else that could cause interference though. I don't mean to hide my URLs, but because I'm interacting with a local server, I figured I would go for readability instead. – Steven Liekens May 14 '12 at 23:40

1 Answers1

0

Special thanks @mellamokb for trying to figure it out with me, but the solution was actually something none of you could've known.

I was stupid enough to write post data to the requeststream before setting the request timeout. I guess that's what you get for trying to write code when you're tired.

Thanks again for your time.

Steven Liekens
  • 13,266
  • 8
  • 59
  • 85