void _reactor_ReactorException(object sender, ServiceExceptionEventArgs e) { if (UnhandledException != null) UnhandledException(this, new ServiceExceptionEventArgs(e.Kind, e.Exception)); if (_state == ServiceState.Up) { CloseAll(); } if (_state != ServiceState.UpExceptionWait) { _upExceptionWaitFinishAt = DateTime.Now + _upExceptionWaitTimeout; } SetState(ServiceState.UpExceptionWait); e.Handled = true; }
public void RunLoopIteration() { _slotsInUse = true; try { // Build a list of handles in slot order; assume that the slots won't change index // during the run loop: WaitHandle[] handles = new WaitHandle[_slots.Count]; for (int i = 0; i < _slots.Count; i++) { handles[i] = _slots[i].Handle; } // Wait on all of the slots until the next timer is ready to be fired: TimeSpan timeout = _queue.IsEmpty ? _forever : _queue.GetTimeUntilNextFireable(DateTime.Now); int signalledSlotIndex = WaitHandle.WaitAny(handles, timeout, false); if (signalledSlotIndex != WaitHandle.WaitTimeout) { // Fire off the signalled slot: ReactorSlot signalledSlot = _slots[signalledSlotIndex]; if (!signalledSlot.IsPermanent) _slots.RemoveAt(signalledSlotIndex); // (The "handles" array no longer matches the slots list.) try { _slotsInUse = false; signalledSlot.Callback(signalledSlot.Result, signalledSlot.State); } catch (Exception ex) { ServiceExceptionEventArgs args = new ServiceExceptionEventArgs(ServiceExceptionKind.DuringHandler, ex); if (ReactorException != null) ReactorException(this, args); if (!args.Handled) throw; } } } finally { _slotsInUse = false; } // Fire any timers: try { _queue.FireAllFireable(DateTime.Now); } catch (Exception ex) { ServiceExceptionEventArgs args = new ServiceExceptionEventArgs(ServiceExceptionKind.DuringTimer, ex); if (ReactorException != null) ReactorException(this, args); if (!args.Handled) throw; } }