Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a timeout in c#

Tags:

c#

timeout

I am new to c#; I have mainly done Java.

I want to implement a timeout something along the lines:

int now= Time.now();
while(true)
{
  tryMethod();
  if(now > now+5000) throw new TimeoutException();
}

How can I implement this in C#? Thanks!

like image 738
Karan Avatar asked Apr 13 '12 15:04

Karan


People also ask

How to implement timeout in C?

select() timeoutstruct timeval timeout;timeout. tv_sec = 1;timeout. tv_usec = 500000;select(max_socket+1, &copy, 0, 0, &timeout); In this case, select() returns after a socket in fd_set copy is ready to read or after 1.5 seconds has elapsed, whichever is sooner.

What is execution timeout in C?

it means your program is running beyond the time limit. 21st November 2019, 11:16 PM. ✳AsterisK✳ +4. Most codes experiencing Execution timed out note are working with loops.

How many times setTimeout executed?

2 Answers. Show activity on this post. setTimeout will only execute once.


4 Answers

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();
}
like image 118
Scott Chamberlain Avatar answered Sep 28 '22 07:09

Scott Chamberlain


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.

like image 29
JMK Avatar answered Sep 28 '22 06:09

JMK


The question is quite old, but yet another option.

using(CancellationTokenSource cts = new CancellationTokenSource(5000))
{
  cts.Token.Register(() => { throw new TimeoutException(); });
  while(!cts.IsCancellationRequested)
  {
    tryMethod();
  }
}

Technically, you should also propagate the CancellationToken in the tryMethod() to interupt it gracefully.

Working demo: (note I had to remove the exception throwing behavior as .netfiddle doesn't like it.)

https://dotnetfiddle.net/WjRxyk

like image 44
Yan Brunet Avatar answered Sep 28 '22 07:09

Yan Brunet


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();
} 
like image 40
JamieSee Avatar answered Sep 28 '22 07:09

JamieSee