/// <summary> /// 調用函數信息 /// </summary> public class CallFunction { /// <summary> /// 執行函數信息 /// </summary> private readonly FunctionInfo _function = null; /// <summary> /// 重試總數 /// </summary> private int retryCount; public CallFunction(FunctionInfo functionInfo) { if (functionInfo == null) { throw new Exception("functionInfo爲null"); } if (functionInfo.Func == null) { throw new Exception("functionInfo.Func爲null"); } _function = functionInfo; retryCount = functionInfo.RetryCount; } /// <summary> /// 執行 信息 /// </summary> /// <returns></returns> public FunctionResult Invoke() { int timeOutCount = 0; //超時次數 var lisExceptions = new List<RetryException>(); //異常集合 FunctionResult functionResult = new FunctionResult(); //函數返回結果 do { try { AutoResetEvent autoResetEvent = new AutoResetEvent(false); Thread thread = new Thread(() => { try { functionResult.Result = _function.Func.Invoke(); } catch (RetryException retryException) //重試異常,須要外面自定義 { if (retryException.Exception != null) { functionResult.Exception = retryException.Exception; } functionResult.IsRetryException = true; } catch (Exception exception) { functionResult.Result = null; functionResult.Exception = exception; } finally { try { autoResetEvent.Set(); } catch { // ignored } } }) { IsBackground = true, Priority = ThreadPriority.Highest }; thread.Start(); bool autoReset = autoResetEvent.WaitOne(TimeSpan.FromSeconds(_function.TimeOut)); //線程等 try { //thread.Abort(); } catch { // ignored } try { autoResetEvent.Close(); autoResetEvent.Dispose(); } catch { // ignored } if (functionResult.IsRetryException) { Thread.Sleep(1000); //執行失敗在睡眠 1 毫秒 functionResult.IsRetryException = false; throw new RetryException() { Exception = functionResult.Exception }; //重試異常 } if (!autoReset) // { timeOutCount++; //超時次數 _function.RetryCount--; Thread.Sleep(1000); //執行失敗在睡眠 1 毫秒 } else { return functionResult; } } catch (RetryException retryException) //重試異常,須要外面自定義 { _function.RetryCount--; lisExceptions.Add(retryException); } catch (Exception ex) //Exception 異常 { functionResult.Result = null; functionResult.Exception = ex; return functionResult; } } while (_function.RetryCount > 0); functionResult.Result = null; functionResult.Exception = new Exception("執行函數失敗,超時次數:" + timeOutCount + "重試次數:" + (retryCount - _function.RetryCount), lisExceptions.Count > 0 ? lisExceptions[lisExceptions.Count - 1].Exception : null); return functionResult; } ///// <summary> ///// 執行 信息 ///// </summary> ///// <returns></returns> //public FunctionResult Invoke() //{ // int timeOutCount = 0; //超時次數 // var lisExceptions = new List<RetryException>(); //異常集合 // FunctionResult functionResult = new FunctionResult(); //函數返回結果 // do // { // try // { // IAsyncResult iAsyncResult = _function.Func.BeginInvoke(null, null); // if (!iAsyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(_function.TimeOut))) //阻塞當前線程 // { // try // { // if (iAsyncResult.IsCompleted) // { // _function.Func.EndInvoke(iAsyncResult); // } // else // { // _function.Func.EndInvoke(iAsyncResult); // } // } // catch (Exception ex) // { // iAsyncResult.AsyncWaitHandle.Close(); // iAsyncResult.AsyncWaitHandle.Dispose(); // } // timeOutCount++; //超時次數 // //超時從新鏈接 // _function.RetryCount--; // } // else // { // functionResult.Result = _function.Func.EndInvoke(iAsyncResult); // return functionResult; // } // } // catch (RetryException retryException) //重試異常,須要外面自定義 // { // _function.RetryCount--; // lisExceptions.Add(retryException); // } // catch (Exception ex) //Exception 異常 // { // functionResult.Result = null; // functionResult.Exception = ex; // return functionResult; // } // } while (_function.RetryCount > 0); // functionResult.Result = null; // functionResult.Exception = // new Exception("執行函數失敗,超時次數:" + timeOutCount + "重試次數:" + (retryCount - _function.RetryCount), // lisExceptions.Count > 0 ? lisExceptions[lisExceptions.Count - 1].Exception : null); // return functionResult; //} } /// <summary> /// 函數對象信息 /// </summary> public class FunctionInfo { private int _timeout = 20; /// <summary> /// 超時時間 以秒爲單位,默認是20S /// </summary> public int TimeOut { get { return _timeout; } set { _timeout = value; } } /// <summary> /// 重試次數 默認 3次 /// </summary> private int _retryCount = 3; /// <summary> /// 重試次數 默認 3次 /// </summary> public int RetryCount { get { return _retryCount; } set { _retryCount = value; } } /// <summary> /// 沒參數但能夠返回的委託 /// </summary> public Func<dynamic> Func { get; set; } } /// <summary> /// 函數執行結果 /// </summary> public class FunctionResult { /// <summary> ///異常 /// </summary> public Exception Exception { get; set; } /// <summary> /// 返回結果 /// </summary> public dynamic Result { get; set; } /// <summary> /// 是否重試 /// </summary> public bool IsRetryException { get; set; } }
調用方式:函數
//可設置超時時間TimeOut(默認20s)及失敗重試次數RetryCount(默認3次)
CallFunction cf = new CallFunction(new FunctionInfo() { Func = () => Test(1), RetryCount = 0, TimeOut = 5 }); FunctionResult r = cf.Invoke();