2012-11-22 3 views
24

가능한 중복 : 나는 C#에서 코드의 라인에 대한 시간 제한을 설정하는 방법
Set timeout to an operation어떻게 C# 코드의 라인에 대한 시간 제한을 설정하는

. 예 : RunThisLine(SomeMethod(Some Input), TimeSpan.FromSeconds(10)) SomeMethod과 10 초 시간 초과. 미리 감사드립니다.

+1

코드의 "라인"이 협조적입니까? 즉, 어떻게 든 취소를 지원합니까? –

+0

아니요, 회선 처리는 지정된 시간으로 제한되어야합니다. – Hossein

답변

71

당신은 Task Parallel Library을 사용할 수 있습니다. 더 정확하게하려면 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"); 
+3

대단합니다. 'SomeMethod'의 결과는'task.Result' 변수에 있습니다. 감사. – Hossein

+6

타임 아웃이 필요하고 메소드가 취소시 토큰을 처리하지 않는 경우'CancellationToken'을 사용할 필요가 없습니다. 잠깐,'token'없이 오버로드가 발생했습니다. – trapicki

+0

얘들 아,이 _might_ 애플 리케이션의 동작을 변경하십시오 (내 경우) – copa017

5

나는이 같은 것을 사용 (당신은 여러 가지를 처리하는 코드를 실패 추가해야합니다) :

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; 
    } 
+2

참고 :이 시간 초과 후 작업을 취소하지 않습니다. 나는 그것이 그렇게해야한다고 말하지는 않는다 - 이것이 중요한 세부 사항이라고 생각하기 때문에 나는 그것을 언급하고있다. –

9

당신은이를 달성하기 위해 IAsyncResult를하고 액션 클래스/인터페이스를 사용할 수 있습니다.

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."); 
    } 
+2

매우 사용하기 쉽습니다! 그러나 이것도 다른 작업을 죽입니까? (타임 아웃의 경우) –

+0

other task = action * –

관련 문제