And the Choice itself?
There is an inconcistensy with the Choice persitence flags:
1. The Concurrent affairs article claims that: "Choice and Interleave's TeardownReceiverGroup require that their arbiters always be non-persistent"
2. CCR Wiki (on the other hand) gives the following example:
Arbiter.Activate(taskQueue,
Arbiter.Choice(
Arbiter.Receive(true,p,MyIntHandler),
Arbiter.Receive(true,p,MyStringHandler)
)
);
I guess that the persistent flag in Choice will be ignored totally, since the arbiter will be destroyed anyway. Ami I right?
[592 byte] By [
IgorM] at [2008-3-6]
Hi,
What about the Choice itself? It can't be persisted, but it can be reactivated?
I tried to reactivate the same Choice Object:
class
Program {
static
void
Main(string
[] args){
Dispatcher dispatcher = new
Dispatcher(0, "Choice Test"
);DispatcherQueue dq = new
DispatcherQueue("Choice Test Queue"
);Port<string
> stringPort = new
Port<string
>(); Port<int
> intPort = new
Port<int
>();PortSet<string
, int
> portSet = new
PortSet<string
, int
>(stringPort, intPort);stringPort.Post(
"Choose me"
);intPort.Post(1);
//Create a choice object
Choice choice=Arbiter.Choice<string
, int
>(portSet,
delegate
(string
stringMessage){
Console.WriteLine("Message: "
+ stringMessage); },
delegate
(int
numberMessage){
Console.WriteLine("Number: "
+ numberMessage.ToString()); });
Arbiter.Activate(dq, choice); Arbiter.Activate(dq, choice); Console.ReadLine(); }
}
The reactivation doesn't work and second message never arrives. It seems that the Choice object can't be reactivated.
Then I tried to reuse the code recreating the object in each activation:
class
Program {
static
void
Main(string
[] args){
Dispatcher dispatcher = new
Dispatcher(0, "Choice Test"
);DispatcherQueue dq = new
DispatcherQueue("Choice Test Queue"
);Port<string
> stringPort = new
Port<string
>(); Port<int
> intPort = new
Port<int
>();PortSet<string
, int
> portSet = new
PortSet<string
, int
>(stringPort, intPort);stringPort.Post(
"Choose me"
);intPort.Post(1);
//Create a Choice per activation
Arbiter.Activate(dq, GetChoice(portSet));Arbiter.Activate(dq, GetChoice(portSet));Console.ReadLine(); }
private
static
Choice GetChoice(PortSet<string
, int
> portSet){
return Arbiter.Choice<string
, int
>(portSet,delegate
(string
stringMessage){
Console.WriteLine("Message: "
+ stringMessage); },
delegate
(int
numberMessage){
Console.WriteLine("Number: "
+ numberMessage.ToString()); });
}
}
This works fine, but with two pitfalls: create a Choice object per activation, and loose the anonymus delegate access to local variables of first method.
Is there any other way to persist or reuse a Choice Arbiter?
Thanks
YOu will need to use interleave. It gives the same (and better) guarantees than choice and its meant to be persisted, until at least one teardown handler runs
Choice is only for one time handlers, for example dealing with a response with a failure and a success outcome
My example now works with Choice (recreating and reactivating the Choice object).
Choice was atractive because it is simple, but Interleave is best suited.
Thanks George