public static void ShutdownRequest_AfterShuttingDown() { // can not enqueue after shutting down event was enqueued var queue = new ManualEventQueue(); Assert.True(queue.BeginShutdown()); Assert.False(queue.Enqueue(new ShutdownRequestEvent())); // handling is skipped, if a shutting down event is enqueued beforehand queue = new ManualEventQueue(); bool requestDetected = false; queue.Subscribers.Add( DelegateEventHandler.OnShutdownRequest( e => requestDetected = true), weakRef: false); Assert.True(queue.Enqueue(new ShutdownRequestEvent())); // enqueueing succeeds Assert.True(queue.Enqueue(new ShuttingDownEvent())); // shutting down event added Assert.False(requestDetected); Assert.True(queue.HandleNext()); // the request was "handled" successfully Assert.False(requestDetected); // but the handler was not actually invoked // ensure there are no unexpected events in the queue, that could have shifted the position of the request event Assert.True(queue.HandleNext()); // shutting down event Assert.True(queue.HandleNext()); // shut down event Assert.False(queue.HandleNext()); Assert.True(queue.IsShutDown); }
public static void Callback() { var queue = new ManualEventQueue(); var evnt = new TestEvent(); bool handled = false; queue.Enqueue( evnt, onHandled: e => { Assert.True(ReferenceEquals(e, evnt)); handled = true; }); // handled original event Assert.False(handled); Assert.True(queue.HandleNext()); Assert.False(handled); // handle second event, implicitly added Assert.True(queue.HandleNext()); Assert.True(handled); // no other events were added Assert.False(queue.HandleNext()); }
public static void EnqueueReturnValue() { var queue = new ManualEventQueue(); var evnt = new TestEvent(); Assert.True(queue.Enqueue(evnt)); // adding the same event a second time Assert.False(queue.Enqueue(evnt)); // handling it and adding it again is fine however Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); // verify that we only added it once Assert.True(queue.Enqueue(evnt)); // adding suspension queue.EventAdding.Suspend(); Assert.False(queue.Enqueue(new TestEvent())); queue.EventAdding.Resume(); Assert.True(queue.Enqueue(new TestEvent())); // handle all events while (queue.HandleNext()) { ; } // add and handle shutting down event Assert.True(queue.Enqueue(new ShuttingDownEvent())); Assert.False(queue.Enqueue(new ShuttingDownEvent())); // another shutting down event is already enqueued Assert.True(queue.HandleNext()); Assert.False(queue.Enqueue(new TestEvent())); // no more events of any kind can be added }
private static void ChangeToNeighboringState(ManualEventQueue manualQueue) // Running --> Suspended { AppStateChangedEvent.Critical criticalEvent = null; var subscriber = DelegateEventHandler.On <AppStateChangedEvent.Critical>( e => { criticalEvent = e; }); TestApp.MainEventQueue.Subscribers.Add(subscriber); // immediately changes state, using a critical event TestApp.MoveToState(AppState.Suspended); Assert.AreEqual(AppState.Suspended, TestApp.CurrentState); Assert.NotNull(criticalEvent); Assert.AreEqual(AppState.Running, criticalEvent.OldState); Assert.AreEqual(AppState.Suspended, criticalEvent.NewState); // followed by a regular event Assert.True(manualQueue.HandleNext(out var evnt)); var regularEvent = (AppStateChangedEvent.Regular)evnt; Assert.AreEqual(AppState.Suspended, regularEvent.CurrentState); TestApp.MainEventQueue.Subscribers.Remove(subscriber); }
public static void HandleSupportsEventInheritance() { var queue = new ManualEventQueue(); var subscriber = new AncestorEventHandler(); queue.Subscribers.AddAll(subscriber); // subscriber does not handle events not in it's inheritance tree Assert.True(queue.Enqueue(new TestEvent())); Assert.True(queue.HandleNext()); Assert.Null(subscriber.LastEventHandled); // subscriber accepts event type it explicitly stated it would handle var namedEvent = new NamedEvent("name"); Assert.True(queue.Enqueue(namedEvent)); Assert.True(queue.HandleNext()); Assert.AreSame(namedEvent, subscriber.LastEventHandled); // subscriber accepts event that inherit what it declared it would handle var derivedEvent = new DescendantEvent(); Assert.True(queue.Enqueue(derivedEvent)); Assert.True(queue.HandleNext()); Assert.AreSame(derivedEvent, subscriber.LastEventHandled); }
public static void StatelessHandler() { var queue = new ManualEventQueue(); // create subscriber TestEvent lastEventHandled = null; var subscriber = DelegateEventHandler.On <TestEvent>(evnt => lastEventHandled = evnt); queue.Subscribers.Add(subscriber); // enqueue and handle event queue.Enqueue(new TestEvent() { Value = 3 }); Assert.Null(lastEventHandled); Assert.True(queue.HandleNext()); // test subscriber Assert.NotNull(lastEventHandled); Assert.AreEqual(3, lastEventHandled.Value); // queue is empty again (no unhandled exceptions or anything else) Assert.False(queue.HandleNext()); }
public static void IsShutDown() { // initially open var queue = new ManualEventQueue(); Assert.False(queue.IsShutDown); // removing all subscribers does not shut down the queue queue.Subscribers.AddAll(new TestEventHandler(), weakRef: false); queue.Subscribers.Clear(); Assert.False(queue.IsShutDown); // adding the shutting down event is not enough queue.BeginShutdown(); Assert.False(queue.IsShutDown); // handling the shutting down event is not enough... queue.Subscribers.Add( DelegateEventHandler.OnShuttingDown( e => queue.Enqueue(new NamedEvent("shutting down event handler"))), weakRef: false); Assert.True(queue.HandleNext()); Assert.False(queue.IsShutDown); // handling the NamedEvent added in the ShuttingDownEvent handler, is not enough Assert.True(queue.HandleNext()); Assert.False(queue.IsShutDown); // ... but handling the ShutDownEvent is Assert.True(queue.HandleNext()); Assert.True(queue.IsShutDown); Assert.False(queue.HandleNext()); }
private static void ChangeToNonNeighboringState(ManualEventQueue manualQueue) // Shutdown --> Running { var criticalEvents = new List <AppStateChangedEvent.Critical>(); var subscriber = DelegateEventHandler.On <AppStateChangedEvent.Critical>( e => criticalEvents.Add(e)); TestApp.MainEventQueue.Subscribers.Add(subscriber); // immediately changes state TestApp.MoveToState(AppState.Running); Assert.AreEqual(AppState.Running, TestApp.CurrentState); // critical events already handled Assert.AreEqual(2, criticalEvents.Count); var criticalEvent = criticalEvents[0]; Assert.AreEqual(AppState.Shutdown, criticalEvent.OldState); Assert.AreEqual(AppState.Suspended, criticalEvent.NewState); criticalEvent = criticalEvents[1]; Assert.AreEqual(AppState.Suspended, criticalEvent.OldState); Assert.AreEqual(AppState.Running, criticalEvent.NewState); // followed by a regular event Assert.True(manualQueue.HandleNext(out var evnt)); var regularEvent = (AppStateChangedEvent.Regular)evnt; Assert.AreEqual(AppState.Running, regularEvent.CurrentState); TestApp.MainEventQueue.Subscribers.Remove(subscriber); }
private static void Constructor(out ManualEventQueue queue) { // try to pass a null event queue Assert.Throws <ArgumentNullException>(() => TestApp.Initialize(null)); // try to pass an event queue that's already shut down var manualQueue = new ManualEventQueue(); manualQueue.BeginShutdown(); while (manualQueue.HandleNext()) { ; } Assert.Throws <ArgumentException>(() => TestApp.Initialize(manualQueue)); // pass a proper event queue manualQueue = new ManualEventQueue(); TestApp.Initialize(manualQueue); Assert.NotNull(AppBase.MainEventQueue); Assert.AreSame(manualQueue, AppBase.MainEventQueue.BaseEventQueue); Assert.AreSame(manualQueue.Subscribers, AppBase.MainEventQueue.Subscribers); Assert.AreSame(manualQueue.EventAdding, AppBase.MainEventQueue.EventAdding); Assert.AreSame(manualQueue.EventHandling, AppBase.MainEventQueue.EventHandling); Assert.AreSame(manualQueue.RaiseUnhandledEvents, AppBase.MainEventQueue.RaiseUnhandledEvents); Assert.AreEqual(AppState.Shutdown, AppBase.CurrentState); queue = manualQueue; }
public static void NullCallback() { var queue = new ManualEventQueue(); Assert.True(queue.Enqueue(new TestEvent(), onHandled: null)); // no exception, successful call Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); // no secondary event added }
public static void EnqueueUpdatesMetadata() { var queue = new ManualEventQueue(); var evnt = new NamedEvent("test"); Assert.Null(evnt.EventEnqueuePos); Assert.True(queue.Enqueue(evnt)); Assert.True(evnt.EventEnqueuePos.Contains(nameof(EnqueueUpdatesMetadata))); }
/// <summary> /// Initializes a new instance of the <see cref="DispatcherEventQueue"/> class. /// </summary> /// <param name="uiDispatcher">The <see cref="Dispatcher"/> to use for event handling.</param> /// <param name="priority">The <see cref="DispatcherPriority"/> to use. Background priority is the default, to keep the UI snappy.</param> public DispatcherEventQueue(Dispatcher uiDispatcher, DispatcherPriority priority = DispatcherPriority.Background) { if (!Enum.IsDefined(typeof(DispatcherPriority), priority)) { throw new ArgumentException("Invalid priority!"); } this.dispatcher = uiDispatcher ?? throw Exc.Null(nameof(uiDispatcher)); this.dispatcherPriority = priority; this.isEventHandlerScheduled = new ThreadSafeBoolean(false); this.manualQueue = new ManualEventQueue(); this.scheduledDelegate = new Action(this.OnScheduled); }
public static void NoNewSubscriptionsAfterShutdown() { var queue = new ManualEventQueue(); var handler = new TestEventHandler(); queue.Subscribers.AddAll(handler); queue.BeginShutdown(); Assert.True(queue.HandleNext()); // shutting down event Assert.True(queue.HandleNext()); // shut down event Assert.True(queue.IsShutDown); Assert.False(queue.Subscribers.RemoveAll(handler)); // a shutdown queue has no subscribers Assert.False(queue.Subscribers.AddAll(new TestEventHandler(), weakRef: false)); }
private static void ShutdownEventTriggersShutdownState(ManualEventQueue manualQueue) { TestApp.MoveToState(AppState.Running); while (manualQueue.HandleNext()) { ; } manualQueue.BeginShutdown(); while (manualQueue.HandleNext()) { ; } Assert.True(manualQueue.IsShutDown); Assert.AreEqual(AppState.Shutdown, TestApp.CurrentState); }
public static void EventsCanNotBeEnqueuedTwice() { var queue = new ManualEventQueue(); var evnt = new TestEvent(); // the same instance twice won't work queue.Enqueue(evnt); queue.Enqueue(evnt); Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); // .. but two separate instances of the same event are fine queue.Enqueue(new TestEvent()); queue.Enqueue(new TestEvent()); Assert.True(queue.HandleNext()); Assert.True(queue.HandleNext()); }
public static void EventsCanNotBeEnqueuedAfterShuttingDown() { var queue = new ManualEventQueue(); var testListener = new TestEventHandler(); queue.Subscribers.AddAll(testListener); queue.Subscribers.Add( DelegateEventHandler.OnShuttingDown( e => queue.Enqueue(new NamedEvent("shutting down event handler"))), weakRef: false); // enqueue shutting down event queue.BeginShutdown(); // can enqueue, after the shutting down event is enqueued, but before it is handled Assert.True(queue.Enqueue(new TestEvent() { Value = 1 })); // handle shutting down event Assert.True(queue.HandleNext()); Assert.Null(testListener.LastEventHandled); // try to enqueue another event, after the shutting down event is handled: // it should have no effect Assert.False(queue.Enqueue(new TestEvent() { Value = 2 })); // handle first test event Assert.True(queue.HandleNext()); Assert.AreEqual(1, ((TestEvent)testListener.LastEventHandled).Value); // handle the event added in the shutting down event handler Assert.True(queue.HandleNext()); Assert.IsInstanceOf <NamedEvent>(testListener.LastEventHandled); // false for null // handle shut down event Assert.True(queue.HandleNext(out var shutDownEvent)); Assert.IsInstanceOf <ShutDownEvent>(shutDownEvent); // nothing more to handle Assert.True(queue.IsShutDown); }
private PackageManagerResponseImpl PerformCall(InvokeMemberBinder binder, object[] args) { using (var eventQueue = new ManualEventQueue()) { // create return message handler var responseHandler = new PackageManagerResponseImpl(); CurrentTask.Events += new GetCurrentRequestId(() => "" + Task.CurrentId); // unhook the old one if it's there. responseHandler.Clear(); // send OG message here! object callResult; base.TryInvokeMember(binder, args, out callResult); // will return when the final message comes thru. eventQueue.StillWorking = true; while (eventQueue.StillWorking && eventQueue.ResetEvent.WaitOne()) { eventQueue.ResetEvent.Reset(); while (eventQueue.Count > 0) { if (!Event <GetResponseDispatcher> .RaiseFirst().DispatchSynchronous(eventQueue.Dequeue())) { eventQueue.StillWorking = false; } } } if (PackageManagerResponseImpl.EngineRestarting) { Logger.Message("Going to try and re issue the call."); // Disconnect(); // the service is going to restart, let's call TryInvokeMember again. EngineServiceManager.WaitForStableMoment(); Connect().Wait(); return(PerformCall(binder, args)); } // this returns the final response back via the Task<*> return(responseHandler); } }
private static void ChangeToSameState(ManualEventQueue manualQueue) { AppStateChangedEvent.Critical criticalEvent = null; var subscriber = DelegateEventHandler.On <AppStateChangedEvent.Critical>( e => { criticalEvent = e; }); TestApp.MainEventQueue.Subscribers.Add(subscriber); var currentState = TestApp.CurrentState; TestApp.MoveToState(currentState); Assert.AreEqual(currentState, TestApp.CurrentState); // no state change Assert.Null(criticalEvent); // no critical event Assert.False(manualQueue.HandleNext()); // no regular event TestApp.MainEventQueue.Subscribers.Remove(subscriber); }
public static void ShuttingDownHandler() { var queue = new ManualEventQueue(); // create subscriber ShuttingDownEvent lastEventHandled = null; var subscriber = DelegateEventHandler.OnShuttingDown(evnt => lastEventHandled = evnt); queue.Subscribers.Add(subscriber); // enqueue and handle event queue.BeginShutdown(); Assert.Null(lastEventHandled); Assert.True(queue.HandleNext()); // shutting down event // test subscriber Assert.NotNull(lastEventHandled); Assert.True(queue.HandleNext()); // shut down event Assert.True(queue.IsShutDown); }
public static void StatefulHandler() { var queue = new ManualEventQueue(); // create subscriber TestEvent lastEventHandled = null; var subscriber = DelegateEventHandler.On( (int currentState, TestEvent evnt) => { lastEventHandled = evnt; evnt.Value += currentState; return(currentState + 1); }, initialState: 10); queue.Subscribers.Add(subscriber); // enqueue events queue.Enqueue(new TestEvent() { Value = 3 }); queue.Enqueue(new TestEvent() { Value = 4 }); Assert.Null(lastEventHandled); // handle first event Assert.True(queue.HandleNext()); Assert.NotNull(lastEventHandled); Assert.AreEqual(13, lastEventHandled.Value); // handle second event Assert.True(queue.HandleNext()); Assert.NotNull(lastEventHandled); Assert.AreEqual(15, lastEventHandled.Value); // queue is empty again (no unhandled exceptions or anything else) Assert.False(queue.HandleNext()); }
public static void ShutdownRequest_NotCancelled() { var queue = new ManualEventQueue(); bool shuttingDownDetected = false; queue.Subscribers.Add( DelegateEventHandler.OnShuttingDown( e => shuttingDownDetected = true), weakRef: false); // requests are granted by default (Cancel is false) Assert.True(queue.RequestShutdown()); Assert.True(queue.HandleNext()); // request event Assert.False(shuttingDownDetected); Assert.True(queue.HandleNext()); // shutting down event Assert.True(shuttingDownDetected); Assert.True(queue.HandleNext()); // shut down event Assert.False(queue.HandleNext()); Assert.True(queue.IsShutDown); }
public static void HandleNextInvokesHandler() { var queue = new ManualEventQueue(); var evnt = new TestEvent(); var subscriber = new TestEventHandler(); // queue empty Assert.False(queue.HandleNext()); // enqueueing does not invoke handlers queue.Subscribers.AddAll(subscriber); Assert.True(queue.Enqueue(evnt)); Assert.Null(subscriber.LastEventHandled); // invoking handlers is successful Assert.True(queue.HandleNext()); Assert.AreSame(evnt, subscriber.LastEventHandled); // queue is empty again Assert.False(queue.HandleNext()); }
public static void EventAddingSuspension() { var queue = new ManualEventQueue(); Assert.False(queue.EventHandling.IsSuspended); var testListener = new TestEventHandler(); queue.Subscribers.AddAll(testListener); var evnt = new TestEvent(); queue.EventAdding.Suspend(); Assert.False(queue.Enqueue(evnt)); Assert.False(queue.HandleNext()); Assert.Null(testListener.LastEventHandled); queue.EventAdding.Resume(); Assert.True(queue.Enqueue(evnt)); Assert.True(queue.HandleNext()); Assert.AreSame(evnt, testListener.LastEventHandled); }
public static void ExceptionHandler() { var queue = new ManualEventQueue(); // create subscriber UnhandledExceptionEvent lastEventHandled = null; var subscriber = DelegateEventHandler.OnException(evnt => lastEventHandled = evnt); queue.Subscribers.Add(subscriber); // enqueue and handle event queue.Enqueue(new UnhandledExceptionEvent(new UnauthorizedAccessException())); Assert.Null(lastEventHandled); Assert.True(queue.HandleNext()); // test subscriber Assert.NotNull(lastEventHandled); Test.OrdinalEquals(lastEventHandled.Type, typeof(UnauthorizedAccessException).ToString()); // queue is empty again (no unhandled exceptions or anything else) Assert.False(queue.HandleNext()); }
public void Disconnect() { _isProcessingMessages.Reset(); lock (this) { _connectingTask = null; try { if (_pipe != null) { // ensure all queues are stopped and cleared out. ManualEventQueue.ResetAllQueues(); _isBufferReady.Set(); var pipe = _pipe; _pipe = null; pipe.Close(); pipe.Dispose(); } } catch { // just close it! } } }
public static void ShutdownRequest_Cancelled() { var queue = new ManualEventQueue(); queue.Subscribers.Add( DelegateEventHandler.OnShutdownRequest( e => e.Cancel = true), weakRef: false); // you can only add one request at a time Assert.True(queue.RequestShutdown()); Assert.False(queue.RequestShutdown()); // cancel the request Assert.True(queue.HandleNext()); // no shutting down event Assert.False(queue.HandleNext()); // you can add another request, once the previous one is out of the queue Assert.True(queue.RequestShutdown()); Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); }
public static void ShutdownRequest_IgnoredAfterShuttingDown() { var queue = new ManualEventQueue(); }
private void ProcessMessages() { var incomingMessage = new byte[BufferSize]; _isBufferReady.Set(); try { // tell others that we are indeed processing messages. _isProcessingMessages.Set(); do { // we need to wait for the buffer to become available. _isBufferReady.WaitOne(); // now we claim the buffer _isBufferReady.Reset(); Task <int> readTask; readTask = _pipe.ReadAsync(incomingMessage, 0, BufferSize); readTask.ContinueWith( antecedent => { if (antecedent.IsCanceled || antecedent.IsFaulted || !IsConnected) { if (antecedent.IsCanceled) { Logger.Message("Client/Session ReadTask is Cancelled"); } if (antecedent.IsFaulted) { Logger.Message("Client/Session ReadTask is Faulted : {0}", antecedent.Exception.GetType()); } Disconnect(); return; } if (antecedent.Result > 0) { var rawMessage = Encoding.UTF8.GetString(incomingMessage, 0, antecedent.Result); var responseMessage = new UrlEncodedMessage(rawMessage); var rqid = responseMessage["rqid"].ToInt32(); // lazy log the response (since we're at the end of this task) Logger.Message("Response:[{0}]{1}".format(rqid, responseMessage.ToSmallerString())); try { var queue = ManualEventQueue.GetQueue(rqid); if (queue != null) { queue.Enqueue(responseMessage); } //else { // GS01 : Need to put in protocol version detection. //} } catch { } } // it's ok to let the next readTask use the buffer, we've got the data out & queued. _isBufferReady.Set(); }).AutoManage(); // this wait just makes sure that we're only asking for one message at a time // but does not throttle the messages themselves. // readTask.Wait(); } while (IsConnected); } catch (Exception e) { Logger.Message("Connection Terminating with Exception {0}/{1}", e.GetType(), e.Message); } finally { Logger.Message("In ProcessMessages/Finally"); Disconnect(); } }
public static void EventHandlerExceptions() { var queue = new ManualEventQueue(); queue.Subscribers.Add( DelegateEventHandler.On <TestEvent>( e => throw new ArgumentOutOfRangeException()), weakRef: false); queue.Subscribers.Add( DelegateEventHandler.On <TestEvent>( e => throw new MissingMemberException()), weakRef: false); bool argumentExceptionFound = false; bool memberExceptionFound = false; bool unhandledExceptionEventHandled = false; queue.Subscribers.Add( DelegateEventHandler.On <UnhandledExceptionEvent>( e => { unhandledExceptionEventHandled = true; if (e.Type.IndexOf(nameof(ArgumentOutOfRangeException), StringComparison.Ordinal) != -1) { argumentExceptionFound = true; } else if (e.Type.IndexOf(nameof(MissingMemberException), StringComparison.Ordinal) != -1) { memberExceptionFound = true; } }), weakRef: false); // unhandled exception events are generated by default queue.Enqueue(new TestEvent()); Assert.False(argumentExceptionFound); Assert.False(memberExceptionFound); Assert.False(unhandledExceptionEventHandled); Assert.True(queue.HandleNext()); // test event Assert.True(queue.HandleNext()); // argument exception Assert.True(queue.HandleNext()); // missing member exception Assert.True(argumentExceptionFound); Assert.True(memberExceptionFound); Assert.True(unhandledExceptionEventHandled); // unhandled exception event suppression queue.Enqueue(new TestEvent()); argumentExceptionFound = false; memberExceptionFound = false; unhandledExceptionEventHandled = false; queue.RaiseUnhandledEvents.Suspend(); Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); queue.RaiseUnhandledEvents.Resume(); Assert.False(argumentExceptionFound); Assert.False(memberExceptionFound); Assert.False(unhandledExceptionEventHandled); // event addition suppression queue.Enqueue(new TestEvent()); queue.EventAdding.Suspend(); Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); queue.EventAdding.Resume(); Assert.False(argumentExceptionFound); Assert.False(memberExceptionFound); Assert.False(unhandledExceptionEventHandled); }