WaitUtil.cs 1.9 KB

using log4net;
using System;
using System.Reflection;
using System.Threading;

namespace Common
{
    public class WaitUtil
    {
        public delegate bool IsOk();
        static readonly LogBean logBean = new LogBean(MethodBase.GetCurrentMethod()?.DeclaringType.FullName);
        /// <summary>
        /// 使用异步委托检测超时,防止isOk方法不返回结果导致卡死的问题
        /// </summary>
        /// <param name="waitName"></param>
        /// <param name="timeout"></param>
        /// <param name="isOk"></param>
        public static bool Wait(int timeout, IsOk isOk, string waitName = "")
        {
            DateTime startTime = System.DateTime.Now;
            TimeSpan timoutSpan = TimeSpan.FromMilliseconds(timeout);
            TimeSpan waitSpan = TimeSpan.FromMilliseconds(0);
            int sleepTime = 10;
            while (true)
            {
                TimeSpan remainTimes = timoutSpan.Subtract(waitSpan);
                if (remainTimes.TotalMilliseconds < 0)
                {
                    //已经超时
                    throw new TimeoutException(waitName + "超时");
                }
                try
                {
                    IAsyncResult re = isOk.BeginInvoke(null, null);
                    var waitResult = re.AsyncWaitHandle.WaitOne(remainTimes);
                    if (waitResult)
                    {
                        bool okResult = isOk.EndInvoke(re);
                        if (okResult)
                        {
                            return true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogUtil.Error("同步等待出现异常",ex,logBean);
                }
                Thread.Sleep(sleepTime);
                waitSpan = System.DateTime.Now.Subtract(startTime);
            }
        }

    }
}