2

I have a method which should execute within given time or it should throw 'Timeout' exception. Basically it has a long running loop. Calculating timeout in every pass of loop seems expensive:

private void DoSomethingGood(int timeoutSeconds)
{
    var startTime=DateTime.Now;
    int count=100000000; //some big number

    for(int i=0;i<count;i++)
    {
        //code to to take care of timeout.
        var ellapsedSeconds =(DateTime.Now-startTime).TotalSeconds;
        if(ellapsedSeconds>=timeoutSeconds)
        {
            throw new TimeoutException("Timeout");
        }

        /*some more code here*/

    }
}

(calling above method without other code, itself is taking more than 2 seconds, largely due to DateTime.Now statement)

Can someone suggest a better way of doing it?

I am fine with +-few-milliseconds.

Falaque
  • 886
  • 2
  • 12
  • 27
  • possible duplicate of [.net construct for while loop with timeout](http://stackoverflow.com/questions/6629219/net-construct-for-while-loop-with-timeout) – jbabey Mar 26 '13 at 12:14
  • Why not use build-in `System.Timers.Timer`? – bash.d Mar 26 '13 at 12:15
  • Your DateTime.Now is NOT taking 2 seconds. If it does, you should check your computer. – Peter Mar 26 '13 at 12:16
  • @peer if you run above code without "DateTime.Now" it finishes very fast. With this statement it takes considerable amount of time. – Falaque Mar 26 '13 at 12:18
  • 1
    Note: you might want to use `UtcNow` instead of `Now` (in both cases) - otherwise it could fail when the timezone / daylight-savings-time changes. – Marc Gravell Mar 26 '13 at 12:22
  • @MarcGravell it wont fail, as I am not taking DateTime from outside. – Falaque Mar 26 '13 at 12:26
  • 1
    DateTime.UtcNow will give you better performance than datetime.now because it will not need to convert the time to your local timezone. This might solve your performance hit. – Peter Mar 26 '13 at 12:26
  • 2
    @Falaque er, yes it will fail. If the loop starts just before daylight-savings time, you might either (depending on the direction of the change) either not detect the timeout at all for an hour (etc), or might detect it incorrectly too early. – Marc Gravell Mar 26 '13 at 12:27
  • @MarcGravell, oops, I dont know this DayLight saving problem, so you mean, DateTime.UtcNow wont fail? – Falaque Mar 26 '13 at 12:28
  • 1
    @Falaque correct; as long as nobody changes the actual system clock itself (which is unrelated to things like timezone and DST settings) – Marc Gravell Mar 26 '13 at 12:41

1 Answers1

4

Only do that check periodically? for example:

if((i % 100) == 0) { /* check for timeout */ }

Or adjust to 1000, 10000 etc depending on how fast it needs to notice the timeout.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Note: you can also improve the test performance by pre-calculating the timeout via `var timeout = startTime.AddSeconds(timeoutSeconds);` and just checking `if(DateTime.[Utc]Now>=timeout)` - but it probably isn't worth it. – Marc Gravell Mar 26 '13 at 12:22
  • thing is checking timeout itself is taking lot of time. – Falaque Mar 26 '13 at 12:25
  • @Falaque hence you check it less often, as per the above. – Marc Gravell Mar 26 '13 at 12:26