using Serein.Library.Enums; using System; using System.Collections.Concurrent; using System.Threading.Tasks; namespace Serein.Library.Framework.NodeFlow.Tool { public class TcsSignalException : Exception { public FlowStateType FsState { get; set; } public TcsSignalException(string message) : base(message) { FsState = FlowStateType.Error; } } public class TcsSignal where TSignal : struct, Enum { //public ConcurrentDictionary>> TcsEvent { get; } = new(); public ConcurrentDictionary> TcsEvent { get; } = new ConcurrentDictionary>(); public ConcurrentDictionary TcsLock { get; } = new ConcurrentDictionary(); /// /// 触发信号 /// /// /// 信号 /// 传递的参数 /// 是否成功触发 public bool TriggerSignal(TSignal signal, T value) { var tcsLock = TcsLock.GetOrAdd(signal, new object()); lock (tcsLock) { if (TcsEvent.TryRemove(signal, out var waitTcs)) { waitTcs.SetResult(value); return true; } return false; } } public TaskCompletionSource CreateTcs(TSignal signal) { var tcsLock = TcsLock.GetOrAdd(signal, new object()); lock (tcsLock) { var tcs = TcsEvent.GetOrAdd(signal, new TaskCompletionSource()); return tcs; } } public void CancelTask() { foreach (var tcs in TcsEvent.Values) { tcs.SetException(new TcsSignalException("任务取消")); } TcsEvent.Clear(); } } }