我们经常有这样的需求:如果一个方法的执行,超过了一个设定时间(timeout)就需要立即返回不再继续,这里我利用 C# 异步委托的 AsyncWaitHandle 来尽量简便的实现这一需求。
具体实现如下。注意,这里需要被调用的方法遵守 delegate TR TimeOutDelegate(T param); 形式的方法签名,如有其他需要,可以自行定制也很方便。
namespace TimeOutHelper { #region using directives using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; #endregion using directives internal class Program { public delegate TR TimeOutDelegate<in T, out TR>(T param); private static void Main() { Dictionary<Guid, string> result; Console.WriteLine(TimeoutFunction.Execute(Test, "Hello, World!", out result, TimeSpan.FromSeconds(3))); Console.WriteLine("Hello, World!"); Console.ReadKey(); } public static Dictionary<Guid, string> Test(string sourceString) { var result = sourceString.ToDictionary( character => Guid.NewGuid(), character => character.ToString(CultureInfo.InvariantCulture)); Thread.Sleep(4000); return result; } public static class TimeoutFunction { /// <summary> /// Execute a method with timeout check /// </summary> /// <typeparam name="T">Target method parameter type</typeparam> /// <typeparam name="TR">The result type of execution</typeparam> /// <param name="timeoutMethod">Target method</param> /// <param name="param">Target method parameter</param> /// <param name="result">The result of execution</param> /// <param name="timeout">Set timeout length</param> /// <returns>Is timeout</returns> public static Boolean Execute<T, TR>( TimeOutDelegate<T, TR> timeoutMethod, T param, out TR result, TimeSpan timeout) { var asyncResult = timeoutMethod.BeginInvoke(param, null, null); if (!asyncResult.AsyncWaitHandle.WaitOne(timeout, false)) { result = default(TR); return true; } result = timeoutMethod.EndInvoke(asyncResult); return false; } } } }