I have a created a thread that has a dispatcher run for processing low level mouse hook events, and created a DispatcherTimer based on this dispatcher.
When DispatcherTimer.Tick() was fired, I simulated another mouse down message. Then something strange happend: The Dispatcher.Tick() was interupted and mouse hook event fired in the same thread. After the mouse hook event processed, the DispatcherTimer.Tick() continues to end.
From what I understand, the dispatcher will process tasks one by one, so it should execute the DispatcherTimer.Tick() method completely, then other hook events.
Is this behaivor normal? Is there anyway that I can ensure DispatcherTimer.Tick() was executed completely before hook event fired?
Creating dispatcher thread:
public static class DispatcherBuilder
{
public static Dispatcher Build()
{
Dispatcher dispatcher = null;
var manualResetEvent = new ManualResetEvent(false);
var thread = new Thread(() =>
{
dispatcher = Dispatcher.CurrentDispatcher;
var synchronizationContext = new DispatcherSynchronizationContext(dispatcher);
SynchronizationContext.SetSynchronizationContext(synchronizationContext);
manualResetEvent.Set();
try
{
Dispatcher.Run();
}
catch
{
// ignore
}
}, maxStackSize:1);
thread.Priority = ThreadPriority.Normal;
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
manualResetEvent.WaitOne();
manualResetEvent.Dispose();
return dispatcher;
}
}
Code for creating timer and hook setup:
// creating disapatcher:
_hookDispatcher = DispatcherBuilder.Build();
// creating timer on the dispatcher
_mouseDownTimer = new DispatcherTimer(DispatcherPriority.Normal, _hookDispatcher);
_mouseDownTimer.Tick += new EventHandler(mouseDownTimer_Tick);
_mouseDownTimer.Interval = TimeSpan.FromMilliseconds(_dataService.Settings.RightBtnPopupDelayMs);
// create hook
_hookDispatcher.Invoke(() =>
{
_mouseHook = new MouseHook();
_mouseHook.MouseUp += MouseHookOnMouseUp;
_mouseHook.MouseDown += MouseHookOnMouseDown;
_mouseHook.MouseWheel += MouseHookOnMouseWheel;
_mouseHook.MouseMove += MouseHookOnMouseMove;
_mouseHook.MouseHWheel += MouseHookOnMouseHWheel;
_mouseHook.Start();
});
The following is some Debug.WriteLine() output:
177,250 MouseDown Right Thread:14
177,250 MouseDown Right Captured Thread:14
// DeispatcherTimer.Tick() Started
177,360 Timer Tick Begin Thread:14 -- in DeispatcherTimer.Tick()
177,360 Sending RightButtonDown -- in DeispatcherTimer.Tick()
// MouseHookOnMouseUp() called in same thread
177,485 MouseUp Right Thread:14 -- in MouseHookOnMouseUp()
177,500 MouseUp Right Captured Thread:14 -- in MouseHookOnMouseUp()
// MouseHookOnMouseDown() called in same thread
177,500 MouseDown Right Thread:14 -- in MouseHookOnMouseDown()
// Returned to DeispatcherTimer.Tick() in same thread
177,500 Timer Tick End -- in DeispatcherTimer.Tick()
177,500 MouseDown Right Thread:14