using System; using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; namespace NBC { public abstract class NTask : ITask { protected readonly Dictionary _argsDic = new(); protected string _errorMsg; protected float _progress; protected string TaskInfo; public virtual string Info { get => TaskInfo; set => TaskInfo = value; } public NTaskStatus Status { get; protected set; } = NTaskStatus.None; public virtual string ErrorMsg => _errorMsg; public virtual float Progress => _progress; public virtual bool IsRunning => Status == NTaskStatus.Running; public virtual bool IsDone => Status == NTaskStatus.Success || Status == NTaskStatus.Fail; public object this[string argsName] { get { if (_argsDic.TryGetValue(argsName, out var args)) return args; return null; } set => _argsDic[argsName] = value; } public virtual void Stop() { Status = NTaskStatus.None; } public virtual void Run(IRunner runner) { Reset(); runner?.Run(this); } public NTaskStatus Process() { if (Status == NTaskStatus.None) Start(); Status = OnProcess(); CallUpdateListener(); if (Status == NTaskStatus.Success) { _progress = 1; CallCompleteListener(Status); } else if (Status == NTaskStatus.Fail) { _progress = 1; CallCompleteListener(Status); } return Status; } protected virtual void OnStart() { } protected virtual NTaskStatus OnProcess() { return Status; } protected void Finish() { _progress = 1; Status = NTaskStatus.Success; } protected void Fail(string message) { _progress = 1; Status = NTaskStatus.Fail; _errorMsg = message; } private void Start() { Reset(); Status = NTaskStatus.Running; _progress = 0; OnStart(); CallStartListener(); } #region 事件 protected event Action OnStartListener; protected event Action OnCompleteListener; protected event Action OnUpdateListener; public ITask OnStarted(Action callback, bool cover = false) { if (cover) OnStartListener = callback; else OnStartListener += callback; return this; } public ITask OnUpdated(Action callback, bool cover = false) { if (cover) OnUpdateListener = callback; else OnUpdateListener += callback; return this; } public ITask OnCompleted(Action callback, bool cover = false) { if (cover) OnCompleteListener = callback; else OnCompleteListener += callback; return this; } protected void CallStartListener() { OnStartListener?.Invoke(this); } protected void CallCompleteListener(NTaskStatus taskStatus) { OnCompleteListener?.Invoke(this); _taskCompletionSource?.TrySetResult(null); } protected void CallUpdateListener() { OnUpdateListener?.Invoke(this); } #endregion #region 异步编程相关 private TaskCompletionSource _taskCompletionSource; /// /// 异步操作任务 /// public Task Task { get { if (_taskCompletionSource == null) { _taskCompletionSource = new TaskCompletionSource(); if (IsDone) _taskCompletionSource.SetResult(null); } return _taskCompletionSource.Task; } } #endregion #region IEnumerator bool IEnumerator.MoveNext() { return !IsDone; } public virtual void Reset() { Status = NTaskStatus.None; } object IEnumerator.Current => null; #endregion } }