views:

260

answers:

3

I've been using this pattern when I need to control how long various async operations take. I don't mean specifically for WebRequest (I know you can set the timeout property), I just used this as an example for the pattern.

        var request = WebRequest.Create(someUri);

        WebResponse response = null;
        request.BeginGetResponse(result =>
            {
                var asyncRequest = (WebRequest)result.AsyncState;
                response = asyncRequest.EndGetResponse(result);
            }, request);

        DateTime timeout = DateTime.Now.AddSeconds(10);
        while (response == null && DateTime.Now <= timeout)
        {
            Thread.Sleep(0);
        }
        if (response == null) throw new Exception("Timeout!");

Anywhere I read about Thread.Sleep(), I heard it's a baaaad thing to do, but I don't really think this use case abuses it.

I know it is possible that it could be a little bit more than exactly 10 seconds, but that isn't important to me.

So, is this truly a bad way to accomplish what I'm accomplishing, and if so, what is a better way to do it?

EDIT: Perhaps I should clarify what I"m trying to accomplish.

The purpose is to control the maximum amount of time spent waiting on a call. I'm aware that this defeats the purpose of an async call, but the intention was never to be asynchronous, I'm just using it as a means to control when I exit a call.

+6  A: 

The WaitHandles wait methods supports time out, use that. Something like:

  var asyncResult = request.BeginGetResponse(...
  asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(10))
Patrik Hägne
Aha! It seems so obvious!
Daniel Schaffer
A: 

For completeness: to avoid blocking the current thread, use System.Threading.Timer.

Simon Buchan
It seems to me from the code example that the desired behavior is to block the current thread.
Patrik Hägne
Then why make it asynchronous?
Ed Swangren
@Patrik: Yes, but google will probably find this in response "timeout async" or somesuch.@Ed: so you can timeout.
Simon Buchan
+1  A: 

Code looks perfectly fine too me. It's just a way to support timeout property on sync call if there's none in the api. Although I should say you'd better replace this waiting loop with some kind of WaitHandle class, it'll use less resources and I'm sure will look better. Sorry, can't provide the solution since I don't know C# and it's API that well.

vava