Dreamine.Threading.Wpf 1.0.1
이 패키지는 Worker Thread를 직접 생성하거나 제어하지 않습니다. `IDreamineThreadManager`의 상태만 관찰합니다.
로딩중...
검색중...
일치하는것 없음
BatchedDispatcher.cs
이 파일의 문서화 페이지로 가기
1using System;
2using System.Collections.Concurrent;
3using System.Collections.Generic;
4using System.Threading;
5using System.Windows.Threading;
6
8{
33 internal sealed class BatchedDispatcher<T>
34 {
43 public const int MaxBatchSize = 256;
44
53 private readonly Dispatcher _dispatcher;
62 private readonly Action<IReadOnlyList<T>> _onBatch;
71 private readonly DispatcherPriority _priority;
80 private readonly ConcurrentQueue<T> _pending = new();
89 private int _scheduled;
90
131 public BatchedDispatcher(
132 Dispatcher dispatcher,
133 Action<IReadOnlyList<T>> onBatch,
134 DispatcherPriority priority = DispatcherPriority.Background)
135 {
136 _dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
137 _onBatch = onBatch ?? throw new ArgumentNullException(nameof(onBatch));
138 _priority = priority;
139 }
140
157 public void Enqueue(T item)
158 {
159 _pending.Enqueue(item);
160 ScheduleFlushIfNeeded();
161 }
162
171 private void ScheduleFlushIfNeeded()
172 {
173 if (Interlocked.CompareExchange(ref _scheduled, 1, 0) != 0)
174 {
175 return;
176 }
177
178 _dispatcher.BeginInvoke(_priority, new Action(Flush));
179 }
180
197 private void Flush()
198 {
199 try
200 {
201 var buffer = new List<T>(Math.Min(_pending.Count, MaxBatchSize));
202
203 while (buffer.Count < MaxBatchSize && _pending.TryDequeue(out var item))
204 {
205 buffer.Add(item);
206 }
207
208 if (buffer.Count > 0)
209 {
210 _onBatch(buffer);
211 }
212 }
213 finally
214 {
215 Volatile.Write(ref _scheduled, 0);
216
217 if (!_pending.IsEmpty)
218 {
219 ScheduleFlushIfNeeded();
220 }
221 }
222 }
223 }
224}