Share via


Timeout a function call in C#

There are some scenarios when you can't afford to allow any long running external/internal method to take forever and eat up your processing resource. You should time it out if it takes longer than X units.

 There are several ways to do that. I like the way using cancellation token the most.

 Here we are calling GetResult() method which might take longer than 5000ms.Code snippet:

  int QueryTimeOut = 5000; //in ms
 var tokenSource = new CancellationTokenSource();
 CancellationToken token = tokenSource.Token;
 var task = Task.Factory.StartNew(() => queryRun.GetResult(), token);
 timedOut = false;
 
 if (!task.Wait(QueryTimeOut, token))
 {
 timedOut = true;
 message = String.Format(" Method Timed out");
 tokenSource.Cancel();
 return -1;
 }
 Int32 result = Convert.ToInt32(task.Result);
 task.Dispose();
 return result;
 

NOTE: Above code does not kill the GetResult() which still runs in background. To Abort processing of GetResult/ long running method, please see below snippet:

  using System;
 using System.Threading;
 using System.Collections.Generic;
 using System.IO;
 using System.Threading.Tasks;
 
 namespace n
 {
 public class MonitorSample
 {
 
 private static int GetResult()
 {
 int result = 0;
 while (++result < 500)
 {
 Console.WriteLine(result);
 Thread.Sleep(5);
 }
 return result;
 }
 public static void Main(String[] args)
 {
 int QueryTimeOut = 50; //in ms
 int result = 0;
 Boolean timeOut = false;
 ManualResetEvent wait = new ManualResetEvent(false);
 Thread work = new Thread(new ThreadStart(() =>
 {
 //some long running method requiring synchronization
 result = GetResult();
 wait.Set();
 }));
 work.Start();
 Boolean signal = wait.WaitOne(QueryTimeOut);
 if (!signal) {
 work.Abort();
 timeOut = true; 
 }
 Console.WriteLine(String.Format("Result = {0}, timedout = {1}", result, timeOut));
 Console.ReadKey();
 }
 }
 }