protected void Dispatch(object o) { lock (_syncObj) _callingClientStart = DateTime.Now; try { ParameterlessMethod cmd = o as ParameterlessMethod; if (cmd != null) cmd(); InputEvent evt = o as InputEvent; if (evt != null) DispatchEvent(evt); } catch (Exception e) { ServiceRegistration.Get<ILogger>().Error("InputManager: Error dispatching '{0}'", e, o); } finally { bool hideBusyScreen; lock (_syncObj) { hideBusyScreen = _busyScreenVisible; _busyScreenVisible = false; _callingClientStart = null; } if (hideBusyScreen && !IsTerminated) { ISuperLayerManager superLayerManager = ServiceRegistration.Get<ISuperLayerManager>(); superLayerManager.HideBusyScreen(); } } }
protected void Dispatch(object o) { System.Threading.Timer timer; lock (_syncObj) { _callingClientStart = DateTime.Now; // Start a timer to show the busy screen if we don't complete the event within the timeout. // We create a new timer on every event so that we can use it's Dispose(WaitHandle) to // ensure that the callback has either finished or is guaranteed not to run after we have // checked whether to hide the busy screen below. This shouldn't have a negative performance // impact because the Timer class is specifically designed for this scenario. // See comment here: https://referencesource.microsoft.com/#mscorlib/system/threading/timer.cs,32 timer = new System.Threading.Timer(BusyTimeoutTimerCallback, null, BUSY_TIMEOUT, Timeout.InfiniteTimeSpan); } try { ParameterlessMethod cmd = o as ParameterlessMethod; if (cmd != null) { cmd(); } InputEvent evt = o as InputEvent; if (evt != null) { DispatchEvent(evt); } } catch (Exception e) { ServiceRegistration.Get <ILogger>().Error("InputManager: Error dispatching '{0}'", e, o); } finally { // Make sure the timer callback is guaranteed not to run // before checking whether the busy screen has been shown. _timoutTimerResetEvent.Reset(); timer.Dispose(_timoutTimerResetEvent); _timoutTimerResetEvent.WaitOne(); bool hideBusyScreen; lock (_syncObj) { hideBusyScreen = _busyScreenVisible; _busyScreenVisible = false; _callingClientStart = null; } if (hideBusyScreen && !IsTerminated) { ISuperLayerManager superLayerManager = ServiceRegistration.Get <ISuperLayerManager>(); superLayerManager.HideBusyScreen(); } } }