64

重複の可能性:
操作にタイムアウトを設定する

C#でコード行のタイムアウトを設定するにはどうすればよいですか. たとえば 、10 秒のタイムアウトでRunThisLine(SomeMethod(Some Input), TimeSpan.FromSeconds(10)) 実行します。SomeMethod前もって感謝します。

4

3 に答える 3

147

タスク並列ライブラリを使用できます。より正確には、次を使用できます 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");
于 2012-11-22T13:35:04.433 に答える
15

これを実現するには、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.");
}
于 2012-11-22T13:35:45.730 に答える
7

私は次のようなものを使用します(さまざまな失敗に対処するためにコードを追加する必要があります):

    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;
    }
于 2012-11-22T13:28:24.923 に答える