From f9ab9209398711d1b2b50ec1606335f681ca960b Mon Sep 17 00:00:00 2001 From: fengjiayi <12821976+ning_xi@user.noreply.gitee.com> Date: Mon, 25 Aug 2025 11:40:31 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=96=B0=E8=AE=BE=E8=AE=A1=E4=BA=86Fl?= =?UTF-8?q?owContext=E7=9A=84Tag=EF=BC=8C=E4=BB=A5=E4=BE=BF=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=9B=B4=E5=A4=9A=E7=B1=BB=E5=9E=8B=E7=9A=84Tag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Library/Api/IFlowContext.cs | 16 ++++++++-- Library/FlowNode/FlowContext.cs | 55 ++++++++++++++------------------- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/Library/Api/IFlowContext.cs b/Library/Api/IFlowContext.cs index db6a3ea..e2bbad0 100644 --- a/Library/Api/IFlowContext.cs +++ b/Library/Api/IFlowContext.cs @@ -25,13 +25,13 @@ namespace Serein.Library.Api /// bool IsRecordInvokeInfo { get; set; } - /// + /*/// /// 用于同一个流程上下文中共享、存储任意数据 /// 流程完毕时,如果存储的对象实现了 IDisposable 接口,将会自动调用 /// 该属性的 set 仅限内部访问,如需赋值,请通过 SetTag() /// 请谨慎使用,请注意数据的生命周期和内存管理 /// - object? Tag { get; } + object? Tag { get; }*/ /// /// 运行环境 @@ -131,7 +131,7 @@ namespace Serein.Library.Api /// 设置共享对象(在同一个上下文中保持一致) /// /// - void SetTag(object tag); + void SetTag(T tag); /// /// 指定泛型尝试获取共享对象(在同一个上下文中保持一致) @@ -139,12 +139,22 @@ namespace Serein.Library.Api /// T? GetTag(); +#if NET6_0_OR_GREATER + /// + /// 指定泛型尝试获取共享对象(在同一个上下文中保持一致) + /// + /// + /// + bool TryGetTag([NotNullWhen(true)] out T? tag); +#else /// /// 指定泛型尝试获取共享对象(在同一个上下文中保持一致) /// /// /// bool TryGetTag(out T? tag); +#endif + /// /// 重置流程状态(用于对象池回收) diff --git a/Library/FlowNode/FlowContext.cs b/Library/FlowNode/FlowContext.cs index 904c9c0..9d46f4c 100644 --- a/Library/FlowNode/FlowContext.cs +++ b/Library/FlowNode/FlowContext.cs @@ -6,6 +6,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Reactive.Concurrency; using System.Security.Cryptography.X509Certificates; using System.Threading; @@ -28,16 +29,6 @@ namespace Serein.Library RunState = RunState.Running; } - /// - /// 用于同一个流程上下文中共享、存储任意数据 - /// 流程完毕时,如果存储的对象实现了 IDisposable 接口,将会自动调用 - /// 该属性的 set 仅限内部访问,如需赋值,请通过 SetTag() - /// 请谨慎使用,请注意数据的生命周期和内存管理 - /// - public object? Tag { get;private set; } - - - /// /// 是否记录流程调用信息 /// @@ -260,18 +251,18 @@ namespace Serein.Library throw new InvalidOperationException($"透传{nodeModel}节点数据时发生异常:上一节点不存在数据"); } - private object _tagLockObj = new object(); + private ConcurrentDictionary tags = new ConcurrentDictionary(); /// - /// 设置共享对象,不建议设置非托管对象 + /// 用于同一个流程上下文中共享、存储任意数据,每一个数据通过类型区分 + /// 流程完毕时,如果存储的对象实现了 IDisposable 接口,将会自动调用 + /// 请谨慎使用,请注意数据的生命周期和内存管理 /// /// - public void SetTag(object tag) + public void SetTag(T tag) { - lock (_tagLockObj) - { - Tag = tag; - } + var key = typeof(T); + tags.AddOrUpdate(key, (_) => tag, (o, n) => tag); } /// @@ -285,6 +276,7 @@ namespace Serein.Library return tag; } + #if NET6_0_OR_GREATER /// /// 指定泛型尝试获取共享对象(在同一个上下文中保持一致) @@ -293,16 +285,13 @@ namespace Serein.Library /// public bool TryGetTag([NotNullWhen(true)] out T? tag) { - lock (_tagLockObj) + if (tags.TryGetValue(typeof(T),out var temp) && temp is T t) { - if (Tag is T t) - { - tag = t; - return true; - } - tag = default; - return false; + tag = t; + return true; } + tag = default; + return false; } #else @@ -313,16 +302,14 @@ namespace Serein.Library /// public bool TryGetTag(out T? tag) { - lock (_tagLockObj) - { - if (Tag is T t) + if (tags.TryGetValue(typeof(T),out var temp) && temp is T t) { tag = t; return true; } tag = default; return false; - } + } #endif @@ -333,10 +320,16 @@ namespace Serein.Library /// public void Reset() { - if(Tag is IDisposable disposable) + var tagObjs = tags.Values.ToArray(); + tags.Clear(); + foreach (var tag in tagObjs) { - disposable.Dispose(); // 释放 Tag 中的资源 + if (tag is IDisposable disposable) + { + disposable.Dispose(); // 释放 Tag 中的资源 + } } + this.dictNodeFlowData?.Clear(); ExceptionOfRuning = null; flowInvokeInfos.Clear();