C#: 一个方法执行超时 timeout 检查的实现

我们经常有这样的需求:如果一个方法的执行,超过了一个设定时间(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;
            }
        }
    }
}
Hendry

About Hendry

不经历复杂的简单,只是一种苍白。

发表评论

电子邮件地址不会被公开。