2012-11-22 14 views
24

Olası Çoğalt: i C# kod satırı için zaman aşımı ayarlayabilirsiniz nasıl
Set timeout to an operationnasıl C# kod satırı için zaman aşımını ayarlamak için

. Örneğin 1012 zaman aşımına uğrayan SomeMethod numaralı telefonu kullanarak RunThisLine(SomeMethod(Some Input), TimeSpan.FromSeconds(10)) . Şimdiden teşekkürler.

+1

Bu kod kooperatifi "satırı" mı, yani bir şekilde iptal etmeyi destekliyor mu? –

+0

Hayır, satır işleme belirtilen süre ile sınırlı olmalıdır. – Hossein

cevap

71

Sen Task Parallel Library kullanabilirsiniz. Daha kesin olmak gerekirse, sen Task.Wait(TimeSpan) kullanabilirsiniz:

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

Bu harika. 'SomeMethod'un sonucu' task.Result' değişkeninde olacaktır. Teşekkürler. – Hossein

+6

Sadece zaman aşımına ihtiyacınız varsa 'CancellationToken' kullanmak gerekmez ve/veya yönteminiz iptal etme işleminde simgeyi işlemez. Bekle, 'token' olmadan bir aşırı yük var, bu da gayet iyi çalışıyor. – trapicki

+0

Dikkat edin arkadaşlar, bu _might_ uygulamanın davranışını değiştir (benim durumumda olduğu gibi) – copa017

5

Böyle bir şey kullanmak (çeşitli başa kod başarısız eklemek gerekir):

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

Lütfen dikkat: Bu işlem, zaman aşımından sonra işlemi iptal etmez. Bunu yapması gerektiğini söylemiyorum - bunu söylüyorum çünkü bunun önemli bir ayrıntı olduğunu düşünüyorum. –

9

Sen bunu başarmak için ıasyncresult ve Eylem sınıf/arayüzünü kullanabilirsiniz.

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

Kullanması çok kolay! Ama bu da diğer görevi öldürmek mi yoksa? (zaman aşımı durumunda) –

+0

diğer görev = action * –