using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
using Fort23.UTool;
namespace Fort23.Core
{
public enum AwaiterStatus
{
Pending,
Succeeded,
Faulted,
}
///
/// 这是一个同步等待异步的框架, 如果要使用真正的异步,请使用Task
/// A
///
[AsyncMethodBuilder(typeof(AsyncTaskMethodBuilder))]
public class CTask : ICTaskResult, IAwaitable, IAwaiter
{
private Action _continuation;
private AwaiterStatus state;
private Exception _exception;
private static readonly Queue queue = new Queue();
public int currIndex = 0;
static int allIndex = 0;
public static bool isHindPool=false;
///
/// 创建 的新实例,并得到一个可以用于报告操作执行完毕的委托。
///
///
/// 创建好的 的新实例,将此返回值作为方法的返回值可以让方法支持 await 异步等待。
///
public static CTask Create(bool isPool=true)
{
#if !COMBAT_SERVER
lock (queue)
{
if (queue.Count == 0||!isPool||isHindPool)
{
CTask cTask = new CTask();
allIndex++;
cTask.currIndex = allIndex;
return cTask;
}
CTask value = queue.Dequeue();
value.state = AwaiterStatus.Pending;
return value;
}
#endif
return new CTask();
// var task = new CTask();
// return task;
}
private CTask()
{
}
public CTask GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get { return this.state != AwaiterStatus.Pending; }
}
public void OnCompleted(Action continuation)
{
if (IsCompleted)
{
continuation?.Invoke();
}
else
{
_continuation += continuation;
}
}
// private T Result { get; set; }
///
/// 这个方法在return await CTask的时候自动调用
///
public void GetResult()
{
if (_exception != null)
{
ExceptionDispatchInfo.Capture(_exception).Throw();
}
Recycle();
}
///
/// 调用此方法以报告任务结束,并指定返回值和异步任务中的异常。
/// 当使用 静态方法创建此类型的实例后,调用方可以通过方法参数中传出的委托来调用此方法。
///
/// 异步操作中的异常。
public void SetResult(Exception exception = null)
{
_exception = exception;
if (AwaiterStatus.Faulted == state)
{
return;
}
this.state = AwaiterStatus.Succeeded;
if (_continuation != null)
{
_continuation.Invoke();
}
}
public void SetResult()
{
SetResult(null);
}
///
///
///
///
public void SetException(Exception exception)
{
this.state = AwaiterStatus.Faulted;
_exception = exception;
LogTool.Error(_exception);
}
private void Recycle()
{
_continuation = null;
_exception = null;
if (state == AwaiterStatus.Pending)
{
return;
}
this.state = AwaiterStatus.Pending;
#if !COMBAT_SERVER
lock (queue)
{
// 太多了
if (queue.Count > 300||isHindPool)
{
return;
}
if (queue.Contains(this))
{
return;
}
queue.Enqueue(this);
}
#endif
}
public override async Task AwaitTask()
{
await this;
}
}
///
/// 这是一个同步等待异步的框架, 如果要使用真正的异步,请使用Task
/// A
///
///
[AsyncMethodBuilder(typeof(AsyncTaskMethodBuilder<>))]
public class CTask : ICTaskResult, IAwaitable, T>, IAwaiter
{
private Action _continuation;
private AwaiterStatus state;
private Exception _exception;
#if !COMBAT_SERVER
private static readonly Queue> queue = new Queue>();
#endif
public static bool isHindPool=false;
///
/// 创建 的新实例,并得到一个可以用于报告操作执行完毕的委托。
///
///
/// 创建好的 的新实例,将此返回值作为方法的返回值可以让方法支持 await 异步等待。
///
public static CTask Create(bool isPool=true)
{
#if !COMBAT_SERVER
lock (queue)
{
if (queue.Count == 0||!isPool||isHindPool)
{
return new CTask();
}
CTask value = queue.Dequeue();
value.state = AwaiterStatus.Pending;
return value;
}
#endif
return new CTask();
// var task = new CTask();
// return task;
}
private CTask()
{
}
public CTask GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get { return state != AwaiterStatus.Pending; }
}
public void OnCompleted(Action continuation)
{
if (IsCompleted)
{
continuation?.Invoke();
}
else
{
_continuation += continuation;
}
}
private T _result;
public T Result
{
get { return _result; }
}
///
/// 这个方法在return await CTask的时候自动调用
///
///
public T GetResult()
{
if (_exception != null)
{
ExceptionDispatchInfo.Capture(_exception).Throw();
}
Recycle();
return _result;
}
///
/// 调用此方法以报告任务结束,并指定返回值和异步任务中的异常。
/// 当使用 静态方法创建此类型的实例后,调用方可以通过方法参数中传出的委托来调用此方法。
///
/// 异步返回值。
/// 异步操作中的异常。
public void SetResult(T result, Exception exception = null)
{
_result = result;
_exception = exception;
if (this.state == AwaiterStatus.Faulted)
{
return;
}
this.state = AwaiterStatus.Succeeded;
if (_continuation != null)
{
_continuation.Invoke();
}
}
///
///
///
///
public void SetException(Exception exception)
{
this.state = AwaiterStatus.Faulted;
_exception = exception;
LogTool.Error(_exception);
}
private void Recycle()
{
_continuation = null;
_exception = null;
if (state == AwaiterStatus.Pending)
{
return;
}
this.state = AwaiterStatus.Pending;
#if !COMBAT_SERVER
lock (queue)
{
// 太多了,回收一下
if (queue.Count > 300||isHindPool)
{
return;
}
if (queue.Contains(this))
{
return;
}
queue.Enqueue(this);
}
#endif
}
public override async Task AwaitTask()
{
await this;
}
}
}