using Newtonsoft.Json.Linq;
using Serein.Library.Api;
using Serein.Library.Utils;
using System;
using System.Collections.Concurrent;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
using System.Transactions;
namespace Serein.Library
{
///
/// 触发类型
///
public enum TriggerDescription
{
///
/// 外部触发
///
External,
///
/// 超时触发
///
Overtime,
///
/// 触发了,但类型不一致
///
TypeInconsistency
}
public class TriggerResult
{
public TriggerDescription Type { get; set; }
public TResult Value { get; set; }
}
///
/// 信号触发器类,带有消息广播功能。
/// 使用枚举作为标记,创建
///
public class TaskFlowTrigger : IFlowTrigger where TSignal : struct, Enum
{
// 使用并发字典管理每个信号对应的广播列表
private readonly ConcurrentDictionary>> _subscribers = new ConcurrentDictionary>>();
///
/// 获取或创建指定信号的 Subject(消息广播者)
///
/// 枚举信号标识符
/// 对应的 Subject
private Subject> GetOrCreateSubject(TSignal signal)
{
return _subscribers.GetOrAdd(signal, _ => new Subject>());
}
///
/// 订阅指定信号的消息
///
/// 枚举信号标识符
/// 订阅者
/// 取消订阅的句柄
private IDisposable Subscribe(TSignal signal, Action> action)
{
IObserver> observer = new Observer>(action);
var subject = GetOrCreateSubject(signal);
return subject.Subscribe(observer); // 返回取消订阅的句柄
}
///
/// 等待触发器并指定超时的时间
///
/// 返回值类型
/// 等待信号
/// 超时时间
///
public async Task> WaitTriggerWithTimeoutAsync(TSignal signal, TimeSpan outTime)
{
var subject = GetOrCreateSubject(signal);
var cts = new CancellationTokenSource();
// 异步任务:超时后自动触发信号
_ = Task.Run(async () =>
{
try
{
await Task.Delay(outTime, cts.Token);
if (!cts.IsCancellationRequested) // 如果还没有被取消
{
var outResult = new TriggerResult