-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUITasks.cs
70 lines (61 loc) · 2.02 KB
/
UITasks.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
#nullable enable
namespace Client
{
public static class UITasks
{
public static readonly List<TaskData> tasks = new List<TaskData>();
private static readonly object TASK_MANIPULATE_LOCK = new object();
private const int MAX_TASK_COUNT = int.MaxValue;
public const int MAX_VISIBLE_TASK_COUNT = 8;
private const string UNKNOWN_TASK_TITLE = "<phantom task>";
#region MUST be used in sync-lock
private static int GetAvailableTaskId()
{
var taskIds = tasks.Select(t => t.Id);
return Enumerable.Range(1, MAX_TASK_COUNT)
.First(id => !taskIds.Contains(id));
}
private static void RemoveTaskById(int id) =>
// the int gets implicitly converted to a TaskData with null title and the right id so Equals() will detect it as same
tasks.Remove(id);
#endregion
public static async Task WithUITask(this Task t, string title)
{
int id;
lock (TASK_MANIPULATE_LOCK)
{
id = GetAvailableTaskId();
tasks.Add(
new TaskData(title ?? UNKNOWN_TASK_TITLE, id)
);
}
try { await t; }
catch { throw; }
finally
{
lock (TASK_MANIPULATE_LOCK) { RemoveTaskById(id); }
}
}
public static async Task<T> WithUITask<T>(this Task<T> t, string? title)
{
int id;
lock (TASK_MANIPULATE_LOCK)
{
id = GetAvailableTaskId();
tasks.Add(
new TaskData(title ?? UNKNOWN_TASK_TITLE, id)
);
}
try { return await t; }
catch { throw; }
finally
{
lock (TASK_MANIPULATE_LOCK) { RemoveTaskById(id); }
}
}
}
}