private bool RaiseEvents(KeyEvent keyEvent, VirtualKey virtualKey) { try { _semaphore.Wait(); // TODO ordered waiting try { var k = virtualKey.ToKey(); var down = keyEvent == KeyEvent.KeyDown || keyEvent == KeyEvent.SystemKeyDown; var args = new KeyEventArgs(k); var l = (down ? KeyDown : KeyUp)?.GetInvocationList(); if (l != null) { for (var i = l.Length; i-- > 0;) { try { var d = l[i]; d.Method.Invoke(d.Target, new object[] { this, args }); } catch { } if (args.Suppress) { return(true); } } } var sys = keyEvent == KeyEvent.SystemKeyDown || keyEvent == KeyEvent.SystemKeyUp; var raw = new RawKeyEventArgs(virtualKey, sys); l = (down ? RawKeyDown : RawKeyUp)?.GetInvocationList(); if (l != null) { for (var i = l.Length; i-- > 0;) { try { var d = l[i]; d.Method.Invoke(d.Target, new object[] { this, raw }); } catch { } if (args.Suppress) { return(true); } } } } finally { _semaphore.Release(); } } catch (ObjectDisposedException) { } return(false); }