Implementing a timeout in c#

One possible way would be:

Stopwatch sw = new Stopwatch();
sw.Start();

while(true)
{
    tryMethod();
    if(sw.ElapsedMilliseconds > 5000) throw new TimeoutException();
}

However you currently have no way to break out of your loop. I would recommend having tryMethod return a bool and change it to:

Stopwatch sw = new Stopwatch();
sw.Start();

while(!tryMethod())
{
    if(sw.ElapsedMilliseconds > 5000) throw new TimeoutException();
}

I think you could do this with a timer and a delegate, my example code is below:

using System;
using System.Timers;

class Program
{
    public delegate void tm();

    static void Main(string[] args)
    {
        var t = new tm(tryMethod);
        var timer = new Timer();
        timer.Interval = 5000;

        timer.Start();

        timer.Elapsed += (sender, e) => timer_Elapsed(t);
        t.BeginInvoke(null, null);
    }

    static void timer_Elapsed(tm p)
    {
        p.EndInvoke(null);
        throw new TimeoutException();
    }

    static void tryMethod()
    {
        Console.WriteLine("FooBar");
    }
}

You have tryMethod, you then create a delegate and point this delegate at tryMethod, then you start this delegate Asynchronously. Then you have a timer, with the Interval being 5000ms, you pass your delegate into your timer elapsed method (which should work as a delegate is a reference type, not an value type) and once the 5000 seconds has elapsed, you call the EndInvoke method on your delegate.


As long as tryMethod() doesn't block this should do what you want:

Not safe for daylight savings time or changing time zones when mobile:

DateTime startTime = DateTime.Now;

while(true)
{
    tryMethod();
    if(DateTime.Now.Subtract(startTime).TotalMilliseconds > 5000)
        throw new TimeoutException();
}

Timezone and daylight savings time safe versions:

DateTime startTime = DateTime.UtcNow;

while(true)
{
    tryMethod();
    if(DateTime.UtcNow.Subtract(startTime).TotalMilliseconds > 5000)
        throw new TimeoutException();
} 

(.NET 3.5 or higher required for DateTimeOffset.)

DateTimeOffset startTime = DateTimeOffset.Now;

while(true)
{
    tryMethod();
    if(DateTimeOffset.Now.Subtract(startTime).TotalMilliseconds > 5000)
        throw new TimeoutException();
} 

Tags:

C#

Timeout