Browse Source

Introduce cross-thread support for AutomaticRawEventGrouperDispatchQueue (#21386)

pull/21394/head
Nikita Tsukanov 5 months ago
committed by GitHub
parent
commit
1ce8302742
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 33
      src/Shared/RawEventGrouping.cs

33
src/Shared/RawEventGrouping.cs

@ -52,35 +52,42 @@ internal class AutomaticRawEventGrouperDispatchQueue : IRawEventGrouperDispatchQ
{ {
private readonly Queue<(RawInputEventArgs args, Action<RawInputEventArgs> handler)> _inputQueue = new(); private readonly Queue<(RawInputEventArgs args, Action<RawInputEventArgs> handler)> _inputQueue = new();
private readonly Action _dispatchFromQueue; private readonly Action _dispatchFromQueue;
private readonly Dispatcher _dispatcher;
public AutomaticRawEventGrouperDispatchQueue() public AutomaticRawEventGrouperDispatchQueue(Dispatcher? dispatcher = null)
{ {
_dispatcher = dispatcher ?? Dispatcher.CurrentDispatcher;
_dispatchFromQueue = DispatchFromQueue; _dispatchFromQueue = DispatchFromQueue;
} }
public void Add(RawInputEventArgs args, Action<RawInputEventArgs> handler) public void Add(RawInputEventArgs args, Action<RawInputEventArgs> handler)
{ {
_inputQueue.Enqueue((args, handler)); lock (_inputQueue)
{
if (_inputQueue.Count == 1) _inputQueue.Enqueue((args, handler));
Dispatcher.UIThread.Post(_dispatchFromQueue, DispatcherPriority.Input);
if (_inputQueue.Count == 1)
_dispatcher.Post(_dispatchFromQueue, DispatcherPriority.Input);
}
} }
private void DispatchFromQueue() private void DispatchFromQueue()
{ {
RawInputEventArgs args;
Action<RawInputEventArgs> handler;
while (true) while (true)
{ {
if(_inputQueue.Count == 0) lock (_inputQueue)
return; if (_inputQueue.Count == 0)
return;
var ev = _inputQueue.Dequeue(); (args, handler) = _inputQueue.Dequeue();
ev.handler(ev.args);
if (Dispatcher.UIThread.HasJobsWithPriority(DispatcherPriority.Input + 1)) handler(args);
if (_dispatcher.HasJobsWithPriority(DispatcherPriority.Input + 1))
{ {
Dispatcher.UIThread.Post(_dispatchFromQueue, DispatcherPriority.Input); _dispatcher.Post(_dispatchFromQueue, DispatcherPriority.Input);
return; return;
} }
} }

Loading…
Cancel
Save