mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-12 04:29:25 +08:00
修改了logwindows输出,避免高频输出时卡死。修改了流程运行上下文,使节点具备终止分支运行的能力。
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
using System.Windows;
|
||||
|
||||
namespace Serein.WorkBench.Tool.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据bool类型控制可见性
|
||||
/// </summary>
|
||||
[ValueConversion(typeof(bool), typeof(Visibility))]
|
||||
public class InvertableBooleanToVisibilityConverter : IValueConverter
|
||||
{
|
||||
enum Parameters
|
||||
{
|
||||
Normal, Inverted
|
||||
}
|
||||
|
||||
public object Convert(object value, Type targetType,
|
||||
object parameter, CultureInfo culture)
|
||||
{
|
||||
var boolValue = (bool)value;
|
||||
var direction = (Parameters)Enum.Parse(typeof(Parameters), (string)parameter);
|
||||
|
||||
if (direction == Parameters.Inverted)
|
||||
return !boolValue ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
return boolValue ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object? ConvertBack(object value, Type targetType,
|
||||
object parameter, CultureInfo culture)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
79
WorkBench.Remote/Tool/Converters/ThumbPositionConverter.cs
Normal file
79
WorkBench.Remote/Tool/Converters/ThumbPositionConverter.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Serein.WorkBench.Tool.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// 画布拉动范围距离计算器
|
||||
/// </summary>
|
||||
public class RightThumbPositionConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (value is double width)
|
||||
return width - 10; // Adjust for Thumb width
|
||||
return 0;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 画布拉动范围距离计算器
|
||||
/// </summary>
|
||||
public class BottomThumbPositionConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (value is double height)
|
||||
return height - 10; // Adjust for Thumb height
|
||||
return 0;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 画布拉动范围距离计算器
|
||||
/// </summary>
|
||||
public class VerticalCenterThumbPositionConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (value is double height)
|
||||
return height / 2 - 5; // Centering Thumb vertically
|
||||
return 0;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 画布拉动范围距离计算器
|
||||
/// </summary>
|
||||
public class HorizontalCenterThumbPositionConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (value is double width)
|
||||
return width / 2 - 5; // Centering Thumb horizontally
|
||||
return 0;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
26
WorkBench.Remote/Tool/Converters/TypeToColorConverter.cs
Normal file
26
WorkBench.Remote/Tool/Converters/TypeToColorConverter.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Serein.Library.Enums;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Serein.WorkBench.Tool.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据控件类型切换颜色
|
||||
/// </summary>
|
||||
public class TypeToColorConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
// 根据 ControlType 返回颜色
|
||||
return value switch
|
||||
{
|
||||
NodeControlType.Action => Brushes.Blue,
|
||||
NodeControlType.Flipflop => Brushes.Green,
|
||||
_ => Brushes.Black,
|
||||
};
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
85
WorkBench.Remote/Tool/LogTextWriter.cs
Normal file
85
WorkBench.Remote/Tool/LogTextWriter.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace Serein.WorkBench.tool
|
||||
{
|
||||
/// <summary>
|
||||
/// 可以捕获类库输出的打印输出
|
||||
/// </summary>
|
||||
public class LogTextWriter : TextWriter
|
||||
{
|
||||
private readonly Action<string> logAction; // 更新日志UI的委托
|
||||
private readonly StringWriter stringWriter = new(); // 缓存日志内容
|
||||
private readonly Channel<string> logChannel = Channel.CreateUnbounded<string>(); // 日志管道
|
||||
private readonly Action clearTextBoxAction; // 清空日志UI的委托
|
||||
private int writeCount = 0; // 写入计数器
|
||||
private const int maxWrites = 500; // 写入最大计数
|
||||
|
||||
public LogTextWriter(Action<string> logAction, Action clearTextBoxAction)
|
||||
{
|
||||
this.logAction = logAction;
|
||||
this.clearTextBoxAction = clearTextBoxAction;
|
||||
|
||||
// 异步启动日志处理任务,不阻塞主线程
|
||||
Task.Run(ProcessLogQueueAsync);
|
||||
}
|
||||
|
||||
public override Encoding Encoding => Encoding.UTF8;
|
||||
|
||||
public override void Write(char value)
|
||||
{
|
||||
stringWriter.Write(value);
|
||||
if (value == '\n')
|
||||
{
|
||||
EnqueueLog();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write(string? value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) return;
|
||||
stringWriter.Write(value);
|
||||
if (value.Contains('\n'))
|
||||
{
|
||||
EnqueueLog();
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteLine(string? value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) return;
|
||||
stringWriter.WriteLine(value);
|
||||
EnqueueLog();
|
||||
}
|
||||
|
||||
// 将日志加入通道
|
||||
private void EnqueueLog()
|
||||
{
|
||||
var log = stringWriter.ToString();
|
||||
stringWriter.GetStringBuilder().Clear();
|
||||
|
||||
if (!logChannel.Writer.TryWrite(log))
|
||||
{
|
||||
// 如果写入失败(不太可能),则直接丢弃日志或处理
|
||||
}
|
||||
}
|
||||
|
||||
// 异步处理日志队列
|
||||
private async Task ProcessLogQueueAsync()
|
||||
{
|
||||
await foreach (var log in logChannel.Reader.ReadAllAsync()) // 异步读取日志通道
|
||||
{
|
||||
logAction?.Invoke(log); // 执行日志写入到UI的委托
|
||||
|
||||
writeCount++;
|
||||
if (writeCount >= maxWrites)
|
||||
{
|
||||
clearTextBoxAction?.Invoke(); // 清空文本框
|
||||
writeCount = 0; // 重置计数器
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user