CCR tips and tricks - part 20
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.