Expert to Expert: Meijer and Chrysanthakopoulos - Concurrency, Coordination and the CCR
Jan 17, 2009 at 4:58 PMVolume licensing will be available as well in the next month or so.
Loading User Information from Channel 9
Something went wrong getting user information from Channel 9
Loading User Information from MSDN
Something went wrong getting user information from MSDN
Loading Visual Studio Achievements
Something went wrong getting the Visual Studio Achievements
IEnumerator<ITask> CcrReadFileAsync(string file)
{
var result = new Port<IAsyncResult>();
using (var fs = new FileStream(file,…,FileOptions.Asynchronous))
{
var buf = new byte[fs.Length];
fs.BeginRead(buf, 0, buf.Length, result.Post, null);
yield return result.Receive();
var ar = (IAsyncResult)resultPort.Test();
try {
fs.EndRead(ar);
ProcessData(buf);
} catch { // handle exception }
}
}
Chadk wrote:Seems like a canned version of popfly and workflow. How does this justify that it doesnt seem to bring ALL that much new stuff to the table?
DonSch wrote:George,
I'm wondering if you could comment on the recommended use of ThreadCausalities in CCR (in my case non-DSS environment). I can see that Causalities will be transferred from the current thread to the post operation, and that they are conversely transferred from the ITask back to the executing thread, making the context available to delegates as called from Receivers, etc.
The obvious use is to provide an ExceptionPort that can take care of any unhandled exceptions that might have been thrown during events, etc. I have not really seen too many examples, nor is is clear what the appropriate patterns of use really are..
Possible example: I'm inside an iterator doing a number of yield return operations, etc, to Choices, etc. and may want that iterator to have a way to handle any unhandled exceptions during those operations, so I add a CausalityContext within that iterator.
Then perhaps one of the services that I do a yield return call to (it returning a Choice) decides that it needs a 'nested' causality, so it creates one for it's exception handling (of unhandled exceptions in the dispatcher chain).. Once that service posts back thru the Choice, it appears that the original Iterator has it's restored CausalityContext in place again.
Any insight on the appropriate usage patterns would really be appreciated. Also the intent of the CoordinationPort?
The CCR appears to be an extremely useful library for a vast number off cases and I really appreciate your time in filling in the gaps!
tnx again!
Don
dtspence wrote:George,
Thanks for the reply. Your suggestion worked great. I have another related question.
Could you explain what the runtime does with the return type of IEnumerator<ITask> a little? The runtime seemed to execute the first task, but not the others.
Thanks......
abhishekworld wrote:how to make a bot compatable with robotics studio like boe-bot.....please help
kroki wrote:George,
Can you refer me to a library with similar functionality as the CCR, though for unmanaged C++?
Thanks in advance,
Kroki
dtspence wrote:George,
I am trying to create an alternate receiver that would send a message to all predicates and applicable handlers, versus stopping on a single Predicate match.
There is a problem with my implementation not getting a second pass through the EvaluatorAggregateTask's Execute method after the first yield return. I also tried to return an alternate IEnumerator<> from a List<> and received the same behavior.
I was able to get all the EvaluatorTask<> enqueued by calling the DispatchQueue.Enqueue, not sure if this is correct. Do you know if the framework should be executing all of the tasks returned back in the enumerator? Also please mention anything I look at doing differently.
Thanks.
Code snippets as follows:
public class TestReceiver<T>
: Receiver
{
public TestReceiver(bool persist, IPortReceive port,
params Tuple<Predicate<T>, Handler<T>>[] tuples)
: base(true, port, new EvaluatorAggregateTask<T>(tuples))
{
// no code
}
}internal class EvaluatorAggregateTask<V>
: ITask
{
public IEnumerator<ITask> Execute()
{
foreach (Tuple<Predicate<V>, Handler<V>> tuple in this.tuples)
{
Predicate<V> predicate = (Predicate<V>)tuple.Item0;
Handler<V> handler = (Handler<V>)tuple.Item1;
yield return new EvaluatorTask<V>((PortElement<V>)this[0],
handler, predicate);
}
}
[Rest of ITask implementation here ... ]
}
internal class EvaluatorTask<V>
: ITask
{
public IEnumerator<ITask> Execute()
{
if (this.predicate(this.param.TypedItem) == true)
{
this.handler(this.param.TypedItem);
}
return null;
}
[Rest of ITask implementation here ... ]
}