如何为一行c#代码设置超时

Hos*_*ein 40 c# timeout

可能重复:
将超时设置为操作

如何在c#中为一行代码设置超时.例如 RunThisLine(SomeMethod(Some Input), TimeSpan.FromSeconds(10)) ,SomeMethod以10秒的时间运行.提前致谢.

Car*_*ten 103

您可以使用任务并行库.更确切地说,您可以使用 Task.Wait(TimeSpan):

using System.Threading.Tasks;

var task = Task.Run(() => SomeMethod(input));
if (task.Wait(TimeSpan.FromSeconds(10)))
    return task.Result;
else
    throw new Exception("Timed out");
Run Code Online (Sandbox Code Playgroud)

  • 如果你只是需要超时,则没有必要使用`CancellationToken`,和/或你的方法在取消时不处理令牌.等待有一个没有'令牌'的过载,工作得很好. (6认同)
  • 这很棒.`SomeMethod`的结果将在`task.Result`变量中.谢谢. (4认同)
  • 这是一个很好的解决方案,但是,这不是停止功能。只通知超时。 (3认同)
  • 即使 SomeMethod 在 2 秒内响应,该代码段仍将等待 10 秒。 (3认同)
  • @ValerianPereira:根据 [MSDN](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.wait?view=netframework-4.8#System_Threading_Tasks_Task_Wait_System_TimeSpan_) 不应该(见备注),它会阻塞直到 a) *任务成功完成*,b) 任务抛出异常或 c) 任务超时。 (3认同)

Mo *_*tel 12

您可以使用IAsyncResult和Action类/接口来实现此目的.

public void TimeoutExample()
{
    IAsyncResult result;
    Action action = () =>
    {
        // Your code here
    };

    result = action.BeginInvoke(null, null);

    if (result.AsyncWaitHandle.WaitOne(10000))
         Console.WriteLine("Method successful.");
    else
         Console.WriteLine("Method timed out.");
}
Run Code Online (Sandbox Code Playgroud)

  • 使用非常简单!! 但是,这还会杀死其他任务还是?(如果超时) (2认同)

pau*_*aul 6

我使用这样的东西(你应该添加代码来处理各种失败):

    var response = RunTaskWithTimeout<ReturnType>(
        (Func<ReturnType>)delegate { return SomeMethod(someInput); }, 30);


    /// <summary>
    /// Generic method to run a task on a background thread with a specific timeout, if the task fails,
    /// notifies a user
    /// </summary>
    /// <typeparam name="T">Return type of function</typeparam>
    /// <param name="TaskAction">Function delegate for task to perform</param>
    /// <param name="TimeoutSeconds">Time to allow before task times out</param>
    /// <returns></returns>
    private T RunTaskWithTimeout<T>(Func<T> TaskAction, int TimeoutSeconds)
    {
        Task<T> backgroundTask;

        try
        {
            backgroundTask = Task.Factory.StartNew(TaskAction);
            backgroundTask.Wait(new TimeSpan(0, 0, TimeoutSeconds));
        }
        catch (AggregateException ex)
        {
            // task failed
            var failMessage = ex.Flatten().InnerException.Message);
            return default(T);
        }
        catch (Exception ex)
        {
            // task failed
            var failMessage = ex.Message;
            return default(T);
        }

        if (!backgroundTask.IsCompleted)
        {
            // task timed out
            return default(T);
        }

        // task succeeded
        return backgroundTask.Result;
    }
Run Code Online (Sandbox Code Playgroud)

  • 请注意:超时后不会取消操作.我并不是说它应该这样做 - 我提到它是因为我认为这是一个重要的细节. (5认同)