How to not dispatch work in CCR
Being new to the Robotics team also means I get a chance to do some beginner mistakes with CCR. Let's assume that you have a method that does a lot of work and you want to use CCR to do the work. Before using CCR your code would have looked like this:
1: private void ProcessWithoutCcr()
2: {
3: // Do Work
4: // Do a lot more work that takes a lot of time
5: }
If all the work you're doing is just taking time because it needs to use the CPU the method is actually OK. But if there are a lot of things working with files, network etc you want to use a series of yield returns to split up the execution. If you're not really interested in the result or the methods cannot fail you (as a beginner) wold maybe do something like this:
1: private void DoSomething()
2: {
3: // Do Work
4: }
5:
6: private IEnumerator<ITask> DoSomethingElse()
7: {
8: // Do work that takes a lot of time
9: // and split up with yield returns
10: yield break;
11: }
12:
13: public IEnumerator<ITask> Process()
14: {
15: yield return Arbiter.FromHandler(DoSomething);
16: yield return Arbiter.FromIteratorHandler(DoSomethingElse);
17: }
This will however not work and only DoSomething will be executed. The problem is how the execution IEnumerator<ITask> is implemented in CCR. To get it to work you can use a SuccessFailurePort either by passing it in or by returning it. Both approaches are shown in this example:
1: private SuccessFailurePort DoSomethingWithPort()
2: {
3: // Do Work
4: SuccessFailurePort port = new SuccessFailurePort();
5: port.Post(SuccessResult.Instance);
6: return port;
7: }
8:
9: private IEnumerator<ITask> DoSomethingElseWithPort(SuccessFailurePort port)
10: {
11: // Do work that takes a lot of time
12: // and split up with yield returns
13: port.Post(SuccessResult.Instance);
14: yield break;
15: }
16:
17: public IEnumerator<ITask> ProcessWithPort()
18: {
19: yield return DoSomethingWithPort().Choice(CcrServiceBase.EmptyHandler, CcrServiceBase.EmptyHandler);
20: SuccessFailurePort port = new SuccessFailurePort();
21: SpawnIterator(port, DoSomethingElseWithPort);
22: yield return port.Choice(CcrServiceBase.EmptyHandler, CcrServiceBase.EmptyHandler);
23: }
In this example no real handler is used for the port so it could be simplified with a more simple port type, but the SuccessFailurePort pattern is pretty nifty so why not use it...