In robotics you sometimes work with a sensor that sends data very often but you really just want to handle one message every X seconds. You also just want to handle the last message received since you last handled a message. This can be achieved in a similar way to the resource port in part 19 together with a simple loop to drain a port of events.
1: [TestMethod] 2: public void BasedOnTimeWithMessagesDroped() 3: { 4: var timePort = new Port<DateTime>(); 5: var eventPort = new Port<int>(); 6: var resultPort = new Port<int>(); 7: 8: Arbiter.Activate( 9: dispatcherQueue, 10: Arbiter.JoinedReceive( 11: true, 12: timePort, 13: eventPort, 14: (timer, eventValue) => 15: { 16: try 17: { 18: int valueToUse = eventValue; 19: int v; 20: while (eventPort.Test(out v)) 21: { 22: valueToUse = v; 23: } 24: resultPort.Post(valueToUse); 25: } 26: finally 27: { 28: dispatcherQueue.EnqueueTimer( 29: TimeSpan.FromMilliseconds(100), 30: timePort); 31: } 32: })); 33: dispatcherQueue.EnqueueTimer(TimeSpan.FromMilliseconds(100), timePort); 34: for (int i = 0; i < 100; i++) 35: { 36: Thread.Sleep(TimeSpan.FromMilliseconds(10)); 37: eventPort.Post(i); 38: } 39: var mre = new ManualResetEvent(false); 40: int result = 0; 41: Arbiter.Activate( 42: dispatcherQueue, 43: resultPort.Receive( 44: r => 45: { 46: result = r; 47: mre.Set(); 48: })); 49: Assert.IsTrue(mre.WaitOne(TimeSpan.FromSeconds(3))); 50: Assert.AreNotEqual(0, result); 51: Assert.AreNotEqual(99, result); 52: }
Like with the resource port it is important always enqueue a new timer (line 28+). The code to drain a port and preserve only the last value is line 19 to 23.