Последние авторы
1 |(% style="width:65px" %) |(% style="width:1389px" %){{code language="c#"}}internal class PoolManager<T>
2 : IAsyncDisposable
3 {
4 private readonly Func<Task<T>> _createAction;
5 private readonly Func<Func<Task<T>>, T, ValueTask<T>> _resetAction;
6 private readonly Func<T, ValueTask> _disposeAction;
7 private readonly bool _canCreateNew;
8 private readonly Channel<T> _values;
9
10 #region
11
12 private PoolManager(
13 Func<Task<T>> createAction,
14 Func<Func<Task<T>>, T, ValueTask<T>> resetAction,
15 Func<T, ValueTask> disposeAction,
16 int? fixedSize,
17 IEnumerable<T>? values = null
18 )
19 {
20 _createAction = createAction;
21 _resetAction = resetAction;
22 _disposeAction = disposeAction;
23 _canCreateNew = !fixedSize.HasValue;
24
25 if (fixedSize.HasValue)
26 {
27 _canCreateNew = false;
28 _values = Channel.CreateBounded<T>(fixedSize.Value);
29 }
30 else
31 {
32 _canCreateNew = true;
33 _values = Channel.CreateUnbounded<T>();
34 }
35
36 if (values != null)
37 {
38 foreach (var elem in values)
39 {
40 if (!_values.Writer.TryWrite(elem))
41 {
42 throw new Exception();
43 }
44 }
45 }
46 }
47
48
49 public static PoolManager<T> Create(
50 Func<Task<T>> createAction,
51 Func<Func<Task<T>>, T, ValueTask<T>> resetAction,
52 Func<T, ValueTask> disposeAction
53 )
54 {
55 return new PoolManager<T>(
56 createAction,
57 resetAction,
58 disposeAction,
59 fixedSize: null
60 );
61 }
62
63 public static async Task<PoolManager<T>> CreateFixedAsync(
64 Func<Task<T>> createAction,
65 Func<Func<Task<T>>, T, ValueTask<T>> resetAction,
66 Func<T, ValueTask> disposeAction,
67 int initCount
68 )
69 {
70 var createTasks = Enumerable.Repeat(true, initCount)
71 .Select(e => createAction())
72 .ToArray();
73 await Task.WhenAll(createTasks);
74
75 return new PoolManager<T>(
76 createAction,
77 resetAction,
78 disposeAction,
79 fixedSize: initCount,
80 values: createTasks.Select(e => e.Result)
81 );
82 }
83
84 #endregion
85
86
87 #region
88
89 public async Task<PoolItem> GetAsync()
90 {
91 T value;
92 if (_canCreateNew)
93 {
94 if (!_values.Reader.TryRead(out value!))
95 {
96 value = await _createAction();
97 }
98 }
99 else
100 {
101 value = await _values.Reader.ReadAsync();
102 }
103
104 return new PoolManager<T>.PoolItem(
105 this,
106 value
107 );
108 }
109
110 public async ValueTask DisposeAsync()
111 {
112 List<Task> disposeTasks = new List<Task>(5);
113 while (_values.Reader.TryRead(out var elem))
114 {
115 disposeTasks.Add(
116 _disposeAction(elem).AsTask()
117 );
118 }
119
120 await Task.WhenAll(disposeTasks);
121 }
122
123 #endregion
124
125
126 #region
127
128 public record PoolItem
129 : IAsyncDisposable
130 {
131 private readonly PoolManager<T> _poolManager;
132 public T Value { get; }
133
134
135 public PoolItem(
136 PoolManager<T> poolManager,
137 T value
138 )
139 {
140 _poolManager = poolManager;
141 Value = value;
142 }
143
144 public async ValueTask DisposeAsync()
145 {
146 var value = await _poolManager._resetAction(_poolManager._createAction, Value);
147 if (!_poolManager._values.Writer.TryWrite(value))
148 {
149 throw new Exception();
150 }
151 }
152 }
153
154 #endregion
155 }{{/code}}
156 |(% style="width:65px" %) |(% style="width:1389px" %)[[System. Threading. Channels>>doc:Разработка.NET.Библиотеки.События и потоки.System\. Threading\. Channels.WebHome]]
157 |(% style="width:65px" %) |(% style="width:1389px" %)
158
159