Today I have three recommendations for your CCR methods. For methods that are public interfaces to components I would recommend methods that returns ports like this:
1: public PortSet<ResultType, Exception> DoSomething()
This makes it easy for the consumer (yourself or other developers) to just call the method and then use the port returned. As a consumer I do not need to know how to create the port needed and I think that is convenient. It also means the implementation may complete synchronously or asynchronously. As a caller I don't really care.
For internal helpers I however tend to use the following two variants:
1: private IEnumerator<ITask> DoSomething(PortSet<ResultType, Exception> resultPort)
2: private void DoSomething(PortSet<ResultType, Exception> resultPort)
The first one should only be used if the method itself needs to yield return. If it ends up having a yield break in the end just to pass compilation you should go for the second variant. However if the method is part of an interface definition I always use the first (iterator) variant.
So wait you may think. isn't an interface public and hence should have the variant returning a port? And the answer is yes, if the interface is public. But if the interface is internal and it may make sense to treat it as an internal helper.
I'm not agree with you on all cases. When you have public interface method, and that method need to yield return you have no other choice but to have signature of
public IEnumerator<ITask> DoSomething(PortSet<ResultType, Exception> result).
It not that nice and it's not that pretty but it's the only way to go.
Take it one step further - Most of the components will use Iterleave to control the way messages from ports are handled in the component. If you need to handle some message exclusively and you also want to yield return (due to IO or other long operation) you have to return IEnumerator<ITask> otherwise the Interleave will not keep your exclusiveness.
If we're talking an interface as in a C# interface I agree it's typically better to leave it as a yield return since you don't know what the implementation is going to do.
But if we're talking about an API I personally think returning a port is the best option since it means that the user of the API don't need to deal with creating ports etc; just make the call and get everything served so to speak.