在c#中实现超时

Kar*_*ran 14 c# timeout

我是c#的新手; 我主要做了Java.

我想实现一个超时的东西:

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

我怎样才能在C#中实现它?谢谢!

Sco*_*ain 39

一种可能的方法是:

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

while(true)
{
    tryMethod();
    if(sw.ElapsedMilliseconds > 5000) throw new TimeoutException();
}
Run Code Online (Sandbox Code Playgroud)

但是,您目前无法摆脱循环.我建议tryMethod返回a bool并将其更改为:

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

while(!tryMethod())
{
    if(sw.ElapsedMilliseconds > 5000) throw new TimeoutException();
}
Run Code Online (Sandbox Code Playgroud)

  • 在夏令时方面有问题 (2认同)
  • @Servy 你是对的,编辑了我的答案以使用秒表而不是 DateTime。 (2认同)

Yan*_*net 14

这个问题很老了,但还有另一种选择。

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

Run Code Online (Sandbox Code Playgroud)

从技术上讲,您还应该传播 inCancellationTokentryMethod()优雅地中断它。

工作演示:(请注意,我必须删除异常抛出行为,因为 .netfiddle 不喜欢它。)

https://dotnetfiddle.net/WjRxyk


JMK*_*JMK 6

我想你可以用计时器和委托来完成这个,我的示例代码如下:

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

你有tryMethod,然后你创建一个委托并在tryMethod指向这个委托,然后你异步启动这个委托.然后你有一个计时器,Interval是5000ms,你将你的委托传递给你的计时器经过的方法(它应该作为一个委托是一个参考类型,而不是一个值类型),一旦5000秒过去,你调用EndInvoke你委托的方法.