mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-04 15:26:34 +08:00
更改了拖入的DLL显示名称
尝试添加了web自动化测试(基于Selenium)
This commit is contained in:
@@ -39,7 +39,9 @@ namespace Serein.DynamicFlow
|
||||
/// <summary>
|
||||
/// 动态流程上下文
|
||||
/// </summary>
|
||||
|
||||
public class DynamicContext(IServiceContainer serviceContainer)
|
||||
|
||||
{
|
||||
|
||||
private readonly string contextGuid = "";//System.Guid.NewGuid().ToString();
|
||||
|
||||
@@ -34,19 +34,25 @@ namespace Serein.DynamicFlow
|
||||
/// 方法需要的类型
|
||||
/// </summary>
|
||||
public Type DataType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 方法入参参数名称
|
||||
/// </summary>
|
||||
public string ParameterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 入参值
|
||||
/// </summary>
|
||||
|
||||
public string DataValue { get; set; }
|
||||
|
||||
|
||||
|
||||
public string[] Items { get; set; }
|
||||
|
||||
|
||||
|
||||
|
||||
public ExplicitData Clone() => new()
|
||||
{
|
||||
Index = Index,
|
||||
@@ -64,7 +70,7 @@ namespace Serein.DynamicFlow
|
||||
|
||||
public class MethodDetails
|
||||
{
|
||||
public MethodDetails CpoyNew()
|
||||
public MethodDetails Clone()
|
||||
{
|
||||
return new MethodDetails
|
||||
{
|
||||
@@ -73,37 +79,45 @@ namespace Serein.DynamicFlow
|
||||
MethodDelegate = MethodDelegate,
|
||||
MethodDynamicType = MethodDynamicType,
|
||||
MethodGuid = Guid.NewGuid().ToString(),
|
||||
MethodTips = MethodTips + " Cpoy",
|
||||
//ParameterTypes = ParameterTypes,
|
||||
MethodTips = MethodTips ,
|
||||
ReturnType = ReturnType,
|
||||
MethodName = MethodName,
|
||||
MethodLockName = MethodLockName,
|
||||
//ExplicitDataValues = ExplicitDataValues.Select(it => "").ToArray(),
|
||||
|
||||
ExplicitDatas = ExplicitDatas.Select(it => it.Clone()).ToArray(),
|
||||
//IsExplicits = IsExplicits,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 作用实例
|
||||
/// </summary>
|
||||
|
||||
public Type ActingInstanceType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 作用实例
|
||||
/// </summary>
|
||||
|
||||
public object ActingInstance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 方法GUID
|
||||
/// </summary>
|
||||
|
||||
public string MethodGuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 方法名称
|
||||
/// </summary>
|
||||
|
||||
public string MethodName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 方法委托
|
||||
/// </summary>
|
||||
|
||||
public Delegate MethodDelegate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 节点类型
|
||||
/// </summary>
|
||||
@@ -111,28 +125,36 @@ namespace Serein.DynamicFlow
|
||||
/// <summary>
|
||||
/// 锁名称
|
||||
/// </summary>
|
||||
|
||||
public string MethodLockName { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 方法说明
|
||||
/// </summary>
|
||||
|
||||
public string MethodTips { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 参数内容
|
||||
/// </summary>
|
||||
|
||||
public ExplicitData[] ExplicitDatas { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 出参类型
|
||||
/// </summary>
|
||||
|
||||
public Type ReturnType { get; set; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public bool IsCanConnect(Type returnType)
|
||||
{
|
||||
if (ExplicitDatas.Length == 0)
|
||||
|
||||
@@ -4,7 +4,12 @@ using Serein.DynamicFlow.NodeModel;
|
||||
using Serein.DynamicFlow.Tool;
|
||||
using Serein.Web;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DynamicDemo.Node
|
||||
{
|
||||
@@ -14,13 +19,19 @@ namespace DynamicDemo.Node
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class NodeFlowStarter(IServiceContainer serviceContainer,List<MethodDetails> methodDetails)
|
||||
|
||||
{
|
||||
private readonly IServiceContainer ServiceContainer = serviceContainer;
|
||||
private readonly List<MethodDetails> methodDetails = methodDetails;
|
||||
|
||||
private Action ExitAction = null;
|
||||
|
||||
|
||||
private DynamicContext context = null;
|
||||
|
||||
|
||||
public NodeRunTcs MainCts;
|
||||
|
||||
/// <summary>
|
||||
@@ -28,6 +39,11 @@ namespace DynamicDemo.Node
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
//public async Task RunAsync1(List<NodeBase> nodes)
|
||||
//{
|
||||
// await Task.Run(async ()=> await StartRunAsync(nodes));
|
||||
//}
|
||||
|
||||
public async Task RunAsync(List<NodeBase> nodes)
|
||||
{
|
||||
var startNode = nodes.FirstOrDefault(p => p.IsStart);
|
||||
@@ -109,18 +125,24 @@ namespace DynamicDemo.Node
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if (!DelegateCache.GlobalDicDelegates.TryGetValue(md.MethodName, out Delegate del))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var func = md.ExplicitDatas.Length == 0 ? ((Func<object, object, Task<FlipflopContext>>)del) : ((Func<object, object[], Task<FlipflopContext>>)del);
|
||||
|
||||
while (!MainCts.IsCancellationRequested) // 循环中直到栈为空才会退出
|
||||
{
|
||||
object?[]? parameters = singleFlipFlopNode.GetParameters(context, md);
|
||||
// 调用委托并获取结果
|
||||
|
||||
|
||||
FlipflopContext flipflopContext = await func.Invoke(md.ActingInstance, parameters);
|
||||
|
||||
|
||||
|
||||
if (flipflopContext == null)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Serein.DynamicFlow;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Serein.DynamicFlow.NodeModel
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Serein.DynamicFlow.Tool;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Serein.DynamicFlow.NodeModel
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
using Serein.DynamicFlow.Tool;
|
||||
using Newtonsoft.Json;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Serein.DynamicFlow.NodeModel
|
||||
{
|
||||
@@ -18,12 +23,20 @@ namespace Serein.DynamicFlow.NodeModel
|
||||
/// </summary>
|
||||
public abstract class NodeBase : IDynamicFlowNode
|
||||
{
|
||||
|
||||
public MethodDetails MethodDetails { get; set; }
|
||||
|
||||
|
||||
public string Guid { get; set; }
|
||||
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public bool IsStart { get; set; }
|
||||
|
||||
public string DelegateName { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 运行时的上一节点
|
||||
/// </summary>
|
||||
@@ -63,6 +76,7 @@ namespace Serein.DynamicFlow.NodeModel
|
||||
{
|
||||
MethodDetails md = MethodDetails;
|
||||
object? result = null;
|
||||
|
||||
if (DelegateCache.GlobalDicDelegates.TryGetValue(md.MethodName, out Delegate del))
|
||||
{
|
||||
if (md.ExplicitDatas.Length == 0)
|
||||
@@ -81,16 +95,25 @@ namespace Serein.DynamicFlow.NodeModel
|
||||
object?[]? parameters = GetParameters(context, MethodDetails);
|
||||
if (md.ReturnType == typeof(void))
|
||||
{
|
||||
|
||||
|
||||
((Action<object, object[]>)del).Invoke(md.ActingInstance, parameters);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
result = ((Func<object, object[], object>)del).Invoke(md.ActingInstance, parameters);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
// context.SetFlowData(result);
|
||||
// CurrentData = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -99,6 +122,7 @@ namespace Serein.DynamicFlow.NodeModel
|
||||
{
|
||||
MethodDetails md = MethodDetails;
|
||||
object? result = null;
|
||||
|
||||
if (DelegateCache.GlobalDicDelegates.TryGetValue(md.MethodName, out Delegate del))
|
||||
{
|
||||
if (md.ExplicitDatas.Length == 0)
|
||||
@@ -130,8 +154,12 @@ namespace Serein.DynamicFlow.NodeModel
|
||||
{
|
||||
object?[]? parameters = GetParameters(context, MethodDetails);
|
||||
// 调用委托并获取结果
|
||||
|
||||
|
||||
FlipflopContext flipflopContext = await ((Func<object, object[], Task<FlipflopContext>>)del).Invoke(MethodDetails.ActingInstance, parameters);
|
||||
|
||||
|
||||
|
||||
if (flipflopContext != null)
|
||||
{
|
||||
if (flipflopContext.State == FfState.Cancel)
|
||||
@@ -148,6 +176,7 @@ namespace Serein.DynamicFlow.NodeModel
|
||||
// context.SetFlowData(result);
|
||||
// CurrentData = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -251,7 +280,11 @@ namespace Serein.DynamicFlow.NodeModel
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
parameters[i] = ConvertValue(mdEd.DataValue, mdEd.ExplicitType);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -261,30 +294,42 @@ namespace Serein.DynamicFlow.NodeModel
|
||||
var tmpParameter = PreviousNode?.FlowData?.ToString();
|
||||
if (mdEd.DataType.IsEnum)
|
||||
{
|
||||
|
||||
var enumValue = Enum.Parse(mdEd.DataType, tmpParameter);
|
||||
|
||||
parameters[i] = enumValue;
|
||||
}
|
||||
else if (mdEd.DataType == typeof(string))
|
||||
{
|
||||
|
||||
parameters[i] = tmpParameter;
|
||||
|
||||
}
|
||||
else if (mdEd.DataType == typeof(bool))
|
||||
{
|
||||
|
||||
parameters[i] = bool.Parse(tmpParameter);
|
||||
|
||||
}
|
||||
else if (mdEd.DataType == typeof(int))
|
||||
{
|
||||
|
||||
parameters[i] = int.Parse(tmpParameter);
|
||||
|
||||
}
|
||||
else if (mdEd.DataType == typeof(double))
|
||||
{
|
||||
|
||||
parameters[i] = double.Parse(tmpParameter);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmpParameter != null && mdEd.DataType!= null)
|
||||
{
|
||||
|
||||
parameters[i] = ConvertValue(tmpParameter, mdEd.DataType);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Serein.DynamicFlow.SerinExpression;
|
||||
using Serein.DynamicFlow.Tool;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
@@ -22,8 +23,10 @@ namespace Serein.DynamicFlow.NodeModel
|
||||
/// <summary>
|
||||
/// 条件表达式
|
||||
/// </summary>
|
||||
|
||||
public string Expression { get; set; }
|
||||
|
||||
|
||||
public override object? Execute(DynamicContext context)
|
||||
{
|
||||
// 接收上一节点参数or自定义参数内容
|
||||
|
||||
@@ -12,22 +12,16 @@ namespace Serein.DynamicFlow.NodeModel
|
||||
/// </summary>
|
||||
public class SingleExpOpNode : NodeBase
|
||||
{
|
||||
|
||||
public string Expression { get; set; }
|
||||
|
||||
|
||||
public override object? Execute(DynamicContext context)
|
||||
{
|
||||
//if (PreviousNode != null && PreviousNode.FlowData == null)
|
||||
//{
|
||||
// // 存在
|
||||
// throw new InvalidOperationException("previous node data is null.");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
|
||||
//}
|
||||
var data = PreviousNode?.FlowData;
|
||||
|
||||
var newData = SerinExpressionEvaluator.Evaluate(Expression, data, out bool isChange);
|
||||
|
||||
FlowState = true;
|
||||
Console.WriteLine(newData);
|
||||
if (isChange)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Serein.DynamicFlow.SerinExpression
|
||||
@@ -72,8 +73,10 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
public T Value { get; set; }
|
||||
public T RangeStart { get; set; }
|
||||
public T RangeEnd { get; set; }
|
||||
|
||||
public string ArithmeticExpression { get; set; }
|
||||
|
||||
|
||||
public override bool Evaluate(object obj)
|
||||
{
|
||||
if (obj is T typedObj)
|
||||
@@ -179,8 +182,10 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
}
|
||||
|
||||
public Operator Op { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
|
||||
public override bool Evaluate(object obj)
|
||||
{
|
||||
if (obj is string strObj)
|
||||
@@ -221,7 +226,9 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
public ValueTypeConditionResolver<T>.Operator Op { get; set; }
|
||||
public object? TargetObj { get; set; }
|
||||
public T Value { get; set; }
|
||||
|
||||
public string ArithmeticExpression { get; set; }
|
||||
|
||||
public override bool Evaluate(object? obj)
|
||||
{
|
||||
//object? memberValue = GetMemberValue(obj, MemberPath);
|
||||
@@ -259,10 +266,14 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
|
||||
public class MemberStringConditionResolver : ConditionResolver
|
||||
{
|
||||
|
||||
public string MemberPath { get; set; }
|
||||
|
||||
public StringConditionResolver.Operator Op { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
|
||||
public override bool Evaluate(object obj)
|
||||
{
|
||||
object memberValue = GetMemberValue(obj, MemberPath);
|
||||
@@ -282,7 +293,9 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
string[] members = memberPath[1..].Split('.');
|
||||
foreach (var member in members)
|
||||
{
|
||||
|
||||
if (obj == null) return null;
|
||||
|
||||
Type type = obj.GetType();
|
||||
PropertyInfo? propertyInfo = type.GetProperty(member);
|
||||
FieldInfo? fieldInfo = type.GetField(member);
|
||||
@@ -293,7 +306,9 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
else
|
||||
throw new ArgumentException($"Member {member} not found in type {type.FullName}");
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -308,7 +323,9 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
{
|
||||
return part.Substring(startIndex + 1, endIndex - startIndex - 1);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Serein.DynamicFlow.SerinExpression;
|
||||
@@ -10,7 +11,9 @@ public class SerinConditionParser
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
return ConditionParse(data, expression).Evaluate(data);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -30,10 +33,12 @@ public class SerinConditionParser
|
||||
return ParseSimpleExpression(data, expression);
|
||||
}
|
||||
|
||||
|
||||
bool ContainsArithmeticOperators(string expression)
|
||||
{
|
||||
return expression.Contains('+') || expression.Contains('-') || expression.Contains('*') || expression.Contains('/');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static string GetArithmeticExpression(string part)
|
||||
@@ -44,7 +49,9 @@ public class SerinConditionParser
|
||||
{
|
||||
return part.Substring(startIndex + 1, endIndex - startIndex - 1);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
private static object? GetMemberValue(object? obj, string memberPath)
|
||||
{
|
||||
@@ -81,7 +88,9 @@ public class SerinConditionParser
|
||||
{
|
||||
memberPath = operatorStr;
|
||||
targetObj = GetMemberValue(data, operatorStr);
|
||||
|
||||
type = targetObj.GetType();
|
||||
|
||||
operatorStr = parts[1].ToLower();
|
||||
valueStr = string.Join(' ', parts.Skip(2));
|
||||
}
|
||||
@@ -105,14 +114,16 @@ public class SerinConditionParser
|
||||
valueStr = string.Join(' ', parts.Skip(1));
|
||||
}
|
||||
targetObj = GetMemberValue(data, memberPath);
|
||||
Type tempType = typeStr switch
|
||||
|
||||
Type? tempType = typeStr switch
|
||||
{
|
||||
"int" => typeof(int),
|
||||
"double" => typeof(double),
|
||||
"bool" => typeof(bool),
|
||||
"string" => typeof(string),
|
||||
_ => Type.GetType(typeStr)
|
||||
};
|
||||
type = (tempType ?? Type.GetType(typeStr)) ?? throw new ArgumentException("对象表达式无效的类型声明");
|
||||
type = tempType ?? throw new ArgumentException("对象表达式无效的类型声明");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -92,7 +92,9 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
.Select((p, index) => Convert.ChangeType(parameters[index], p.ParameterType))
|
||||
.ToArray();
|
||||
|
||||
|
||||
return method.Invoke(target, parameterValues);
|
||||
|
||||
}
|
||||
|
||||
private static object GetMember(object target, string memberPath)
|
||||
@@ -100,19 +102,25 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
var members = memberPath.Split('.');
|
||||
foreach (var member in members)
|
||||
{
|
||||
|
||||
if (target == null) return null;
|
||||
|
||||
|
||||
var property = target.GetType().GetProperty(member);
|
||||
if (property != null)
|
||||
{
|
||||
|
||||
target = property.GetValue(target);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var field = target.GetType().GetField(member);
|
||||
if (field != null)
|
||||
{
|
||||
|
||||
target = field.GetValue(target);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -121,7 +129,9 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return target;
|
||||
|
||||
}
|
||||
|
||||
private static object SetMember(object target, string assignment)
|
||||
@@ -139,17 +149,23 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
for (int i = 0; i < members.Length - 1; i++)
|
||||
{
|
||||
var member = members[i];
|
||||
|
||||
var property = target.GetType().GetProperty(member);
|
||||
|
||||
if (property != null)
|
||||
{
|
||||
|
||||
target = property.GetValue(target);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var field = target.GetType().GetField(member);
|
||||
if (field != null)
|
||||
{
|
||||
|
||||
target = field.GetValue(target);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -159,7 +175,9 @@ namespace Serein.DynamicFlow.SerinExpression
|
||||
}
|
||||
|
||||
var lastMember = members.Last();
|
||||
|
||||
var lastProperty = target.GetType().GetProperty(lastMember);
|
||||
|
||||
if (lastProperty != null)
|
||||
{
|
||||
var convertedValue = Convert.ChangeType(value, lastProperty.PropertyType);
|
||||
|
||||
@@ -3,8 +3,11 @@ using Serein.DynamicFlow;
|
||||
using Serein.DynamicFlow.NodeModel;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.DynamicFlow.Tool;
|
||||
|
||||
@@ -38,7 +41,9 @@ public static class DelegateGenerator
|
||||
|
||||
foreach (var method in methods)
|
||||
{
|
||||
|
||||
var methodDetails = CreateMethodDetails(serviceContainer, type, method, assemblyName);
|
||||
|
||||
methodDetailsDictionary.TryAdd(methodDetails.MethodName, methodDetails);
|
||||
}
|
||||
|
||||
@@ -76,6 +81,7 @@ public static class DelegateGenerator
|
||||
var dllTypeMethodName = $"{assemblyName}.{type.Name}.{method.Name}";
|
||||
|
||||
|
||||
|
||||
return new MethodDetails
|
||||
{
|
||||
ActingInstanceType = type,
|
||||
@@ -88,6 +94,7 @@ public static class DelegateGenerator
|
||||
ExplicitDatas = explicitDataOfParameters,
|
||||
ReturnType = method.ReturnType,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private static ExplicitData[] GetExplicitDataOfParameters(ParameterInfo[] parameters)
|
||||
@@ -99,6 +106,9 @@ public static class DelegateGenerator
|
||||
string explicitTypeName = GetExplicitTypeName(it.ParameterType);
|
||||
var items = GetExplicitItems(it.ParameterType, explicitTypeName);
|
||||
if ("Bool".Equals(explicitTypeName)) explicitTypeName = "Select"; // 布尔值 转为 可选类型
|
||||
|
||||
|
||||
|
||||
return new ExplicitData
|
||||
{
|
||||
IsExplicitData = it.GetCustomAttribute(typeof(ExplicitAttribute)) is ExplicitAttribute,
|
||||
@@ -110,6 +120,9 @@ public static class DelegateGenerator
|
||||
DataValue = it.HasDefaultValue ? it.DefaultValue.ToString() : "",
|
||||
Items = items.ToArray(),
|
||||
};
|
||||
|
||||
|
||||
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.DynamicFlow.Tool
|
||||
{
|
||||
|
||||
@@ -29,15 +29,15 @@ namespace Serein.DynamicFlow.Tool
|
||||
{
|
||||
while (waitTcss.Count > 0)
|
||||
{
|
||||
|
||||
waitTcss.Pop().SetResult(state);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
lock (TcsEvent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public TaskCompletionSource<object> CreateTcs(TSignal signal)
|
||||
@@ -46,18 +46,9 @@ namespace Serein.DynamicFlow.Tool
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
TcsEvent.GetOrAdd(signal, _ => new Stack<TaskCompletionSource<object>>()).Push(tcs);
|
||||
return tcs;
|
||||
lock (TcsEvent)
|
||||
{
|
||||
/*if(TcsEvent.TryRemove(signal, out var tcss))
|
||||
{
|
||||
//tcs.TrySetException(new TcsSignalException("试图获取已存在的任务"));
|
||||
throw new TcsSignalException("试图获取已存在的任务");
|
||||
}*/
|
||||
|
||||
|
||||
/*TcsEvent.TryAdd(signal, tcs);
|
||||
return tcs;*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
//public TaskCompletionSource<object> GetOrCreateTcs(TSignal signal)
|
||||
//{
|
||||
|
||||
Reference in New Issue
Block a user