Skip to content

Commit 714f919

Browse files
committed
💾 Feat(TaskSystem): Import SignalTask system from KitX.
1 parent b536d23 commit 714f919

2 files changed

Lines changed: 187 additions & 0 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using Common.BasicHelper.Utils.Extensions;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
namespace Common.BasicHelper.Core.TaskSystem;
8+
9+
public class SignalTask
10+
{
11+
public Queue<Action> Actions { get; } = new();
12+
13+
public bool SignalReusable { get; set; } = false;
14+
15+
public bool ActionsReusable { get; set; } = false;
16+
17+
public SignalTask AddAction(Action action)
18+
{
19+
Actions.Enqueue(action);
20+
21+
return this;
22+
}
23+
24+
public SignalTask ReuseSignal(bool reusable = true)
25+
{
26+
SignalReusable = reusable;
27+
28+
return this;
29+
}
30+
31+
public SignalTask ReuseActions(bool reusable = true)
32+
{
33+
ActionsReusable = reusable;
34+
35+
return this;
36+
}
37+
38+
public SignalTask ExecuteAll(bool? reuseall = null)
39+
{
40+
Actions.ForEach(action => action(), reuseall ?? ActionsReusable);
41+
42+
return this;
43+
}
44+
45+
public async Task<SignalTask> ExecuteAllAsync(bool? reuseall = null, CancellationToken? token = null)
46+
{
47+
await Actions.ForEachAsync(
48+
action => action(),
49+
reuseall ?? ActionsReusable,
50+
token ?? default
51+
);
52+
53+
return this;
54+
}
55+
}
56+
57+
public static class SignalTaskExtensions
58+
{
59+
public static SignalTask AddTo(this Action action, SignalTask task) => task.AddAction(action);
60+
61+
public static SignalTask ExecuteAll(this SignalTask task, bool reuseAll = false)
62+
=> task.ExecuteAll(reuseAll);
63+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
5+
namespace Common.BasicHelper.Core.TaskSystem;
6+
7+
public class SignalTasksManager
8+
{
9+
private readonly Dictionary<string, SignalTask> SignalTasks = new();
10+
11+
/// <summary>
12+
/// 触发信号
13+
/// </summary>
14+
/// <param name="signal">信号名称</param>
15+
/// <returns>任务管理器本身</returns>
16+
internal SignalTasksManager RaiseSignal(string signal)
17+
{
18+
if (SignalTasks.TryGetValue(signal, out var signalTask))
19+
{
20+
signalTask.ExecuteAll();
21+
22+
if (!signalTask.SignalReusable)
23+
SignalTasks.Remove(signal);
24+
}
25+
26+
return this;
27+
}
28+
29+
/// <summary>
30+
/// 信号发生时运行任务
31+
/// </summary>
32+
/// <param name="signal">信号</param>
33+
/// <param name="action">任务</param>
34+
/// <returns>任务管理器本身</returns>
35+
internal SignalTasksManager SignalRun(string signal, Action action, bool reusable = false)
36+
{
37+
if (SignalTasks.TryGetValue(signal, out var signalTask))
38+
signalTask.AddAction(action);
39+
else
40+
SignalTasks.Add(
41+
signal,
42+
new SignalTask()
43+
.ReuseSignal(reusable)
44+
.AddAction(action)
45+
);
46+
47+
return this;
48+
}
49+
50+
/// <summary>
51+
/// 清除所有信号响应任务
52+
/// </summary>
53+
/// <returns>任务管理器本身</returns>
54+
internal SignalTasksManager Clear()
55+
{
56+
SignalTasks.Clear();
57+
58+
return this;
59+
}
60+
61+
/// <summary>
62+
/// 执行任务, 并带有更好的日志显示
63+
/// </summary>
64+
/// <param name="action">要执行的动作</param>
65+
/// <param name="name">日志显示名称</param>
66+
/// <param name="prompt">日志提示</param>
67+
public static void RunTask(
68+
Action action,
69+
string name = nameof(Action),
70+
string prompt = ">>> ",
71+
bool catchException = false,
72+
Action<string>? infoLogger = null,
73+
Action<Exception, string>? errLogger = null)
74+
{
75+
infoLogger?.Invoke($"{prompt}Task `{name}` began.");
76+
77+
if (catchException)
78+
{
79+
try
80+
{
81+
action();
82+
}
83+
catch (Exception e)
84+
{
85+
errLogger?.Invoke(e, $"{prompt}Task `{name}` failed: {e.Message}");
86+
}
87+
}
88+
else action();
89+
90+
infoLogger?.Invoke($"{prompt}Task `{name}` done.");
91+
}
92+
93+
/// <summary>
94+
/// 异步执行任务, 并带有更好的日志显示
95+
/// </summary>
96+
/// <param name="action">要执行的动作</param>
97+
/// <param name="name">任务名称</param>
98+
/// <param name="prompt">日志提示</param>
99+
public static async Task RunTaskAsync(
100+
Action action,
101+
string name = nameof(Action),
102+
string prompt = ">>> ",
103+
bool catchException = false,
104+
Action<string>? infoLogger = null,
105+
Action<Exception, string>? errLogger = null)
106+
{
107+
infoLogger?.Invoke($"{prompt}Task `{name}` began.");
108+
109+
if (catchException)
110+
{
111+
try
112+
{
113+
await Task.Run(action);
114+
}
115+
catch (Exception e)
116+
{
117+
errLogger?.Invoke(e, $"{prompt}Task `{name}` failed: {e.Message}");
118+
}
119+
}
120+
else await Task.Run(action);
121+
122+
infoLogger?.Invoke($"{prompt}Task `{name}` done.");
123+
}
124+
}

0 commit comments

Comments
 (0)