Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

dtspence

dtspence dtspence

Niner since 2006

  • CCR Programming - Jeffrey Richter and George Chrysanthakopoulos

    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.

    georgioc wrote:
    
    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 ... ]
     }



    Hi Tasks never get their execute method called more than once. Persistent receivers even, will clone the task that runs the handler, and call it once for each message.

    To achieve what you want, there is a different approach. Create the alternate receiver, just like you did. In the receiver's Evaluate method (override it) take the IPortElement.Value contents, and essentially broad cast to any other port or handlers you want. Make sure you return true from the Evaluate, so the port does not keep the message in its queue



  • CCR Programming - Jeffrey Richter and George Chrysanthakopoulos

    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 ... ]
     }