using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
|
namespace RichCreator
|
{
|
/// <summary>
|
/// 函数调用帮助单元
|
/// </summary>
|
public class FuncUtils
|
{
|
|
|
/// <summary>
|
/// 支持取消和超时的函数包装
|
/// </summary>
|
/// <typeparam name="T"></typeparam>
|
/// <param name="val">原函数传出值</param>
|
/// <param name="timeoutMillSecond">超时毫秒</param>
|
/// <param name="cancelToken">取消Token</param>
|
/// <param name="method">原函数</param>
|
/// <param name="proidTime">每次尝试中间间隔毫秒数</param>
|
/// <returns></returns>
|
public static bool TimeoutCancelableWrap<T>(out T val, Int32 timeoutMillSecond, CancellationToken cancelToken, Func<TimeoutCancelCallResult<T>> method, Int32 proidTime = 1000)
|
{
|
val = default(T);
|
DateTime expireTimeout = DateTime.Now.AddMilliseconds(timeoutMillSecond);
|
TimeoutCancelCallResult<T> result;
|
G.Instance.RemainTimeWriter(timeoutMillSecond / 1000);
|
while (!cancelToken.IsCancellationRequested)
|
{
|
if (DateTime.Now > expireTimeout)
|
{
|
G.Instance.RemainTimeWriter(-1);
|
return false;
|
}
|
|
result = method();
|
if (result.Result)
|
{
|
G.Instance.RemainTimeWriter(-1);
|
val = result.ReturnVal;
|
return true;
|
}
|
|
Thread.Sleep(proidTime);
|
G.Instance.RemainTimeWriter((Int32)(expireTimeout - DateTime.Now).TotalSeconds);
|
}
|
G.Instance.RemainTimeWriter(-1);
|
return false;
|
}
|
|
|
/// <summary>
|
/// 支持取消和超时的函数包装
|
/// </summary>
|
/// <typeparam name="T"></typeparam>
|
/// <param name="val">原函数传出值</param>
|
/// <param name="timeoutMillSecond">超时毫秒</param>
|
/// <param name="cancelToken">取消Token</param>
|
/// <param name="method">原函数</param>
|
/// <param name="proidTime">每次尝试中间间隔毫秒数</param>
|
/// <returns></returns>
|
public static bool TimeoutCancelableWrap(Int32 timeoutMillSecond, CancellationToken cancelToken, Func<bool> method, Int32 proidTime = 1000)
|
{
|
bool result = false;
|
DateTime expireTimeout = DateTime.Now.AddMilliseconds(timeoutMillSecond);
|
G.Instance.RemainTimeWriter(timeoutMillSecond / 1000);
|
while (!cancelToken.IsCancellationRequested)
|
{
|
if (DateTime.Now > expireTimeout)
|
{
|
G.Instance.RemainTimeWriter(-1);
|
return false;
|
}
|
|
result = method();
|
if (result)
|
{
|
G.Instance.RemainTimeWriter(-1);
|
return true;
|
}
|
|
Thread.Sleep(proidTime);
|
G.Instance.RemainTimeWriter((Int32)(expireTimeout-DateTime.Now).TotalSeconds);
|
}
|
G.Instance.RemainTimeWriter(-1);
|
return false;
|
}
|
|
|
/// <summary>
|
/// 没有变化重试的调用包装
|
/// </summary>
|
/// <param name="workFun">主要工作方法</param>
|
/// <param name="workFinishedDectedFun">检测前面的工作方法是否按预定成功了的方法</param>
|
/// <param name="workDectedTimeoutMs">检测方法超时毫秒数</param>
|
/// <param name="preDectedFun">检测是否还处于之前没调用工作方法的阶段</param>
|
/// <param name="tryCount">重试次数</param>
|
/// <param name="cancellationToken">取消句柄</param>
|
/// <returns></returns>
|
public static bool NoChangeRetryCallWrap(Action workFun, Func<bool> workFinishedDectedFun, Func<bool> preDectedFun,Int32 tryCount=3)
|
{
|
Int32 tryCounter = 0;
|
while (tryCounter<tryCount)
|
{
|
try
|
{
|
workFun();
|
}
|
catch
|
{
|
break;
|
}
|
|
|
bool result = false;
|
try
|
{
|
result = workFinishedDectedFun();
|
}
|
catch
|
{
|
break;
|
}
|
|
if (result)
|
{
|
return true;
|
}
|
|
result = preDectedFun();
|
if (result)
|
{
|
//没有变化,则重试
|
tryCounter++;
|
continue;
|
}
|
return false;
|
}
|
return false;
|
|
}
|
|
|
/// <summary>
|
/// 超时取消回调返回值
|
/// </summary>
|
/// <typeparam name="T"></typeparam>
|
public struct TimeoutCancelCallResult<T>
|
{
|
public TimeoutCancelCallResult(bool result, T returnVal)
|
{
|
this.Result = result;
|
this.ReturnVal = returnVal;
|
}
|
|
public bool Result;
|
|
public T ReturnVal;
|
}
|
}
|
}
|