none
Documentation for Arbiter.ExecuteNow and Arbiter.ExecuteToCompletion is confusing RRS feed

  • Question


  • The documentation states that ExecuteNow “Executes task in the current thread context, blocking the current thread until completion”.

    However, the observed behavior is that ExecuteNow returns before an iterative task is completed. What is the intended behavior? 

    How does this differ from ExecuteToCompletion, which “Activates a task and waits for its completion”? What does “wait for” mean? Evidently the calling thread does not block, either. Instead, it returns an ITask. Is it the returned ITask that "waits for its completion"?

    Monday, August 3, 2009 10:36 PM

Answers

All replies

  • Yes, it is confusing. The behavior is that ExecuteNow *starts* executing the task using the current thread. However, if the task then yields, the original task continues. So it really does not block.

    Here is what George had to say about it:

    ExecuteNow is meant to just launch an iterator task using the current thread, avoiding a context switch. In all other ways it’s the same as Execute or dispatcherQueue.Enqueue()

    Trevor 

    Tuesday, August 4, 2009 3:59 AM
  • so basically if you really want to wait for it to complete, you'd have to set up a port, pass this on to the task, and then wait for something to be received in the port. The task you started should then when it is finished post something in that port.

    Am I right?
    Wednesday, August 5, 2009 2:43 PM
  • Yes, that is a common pattern. If you looked inside the code for ExecuteToCompletion, that's what it does. So it is just a convenience -- it is no more efficient than if you did it yourself. If you just want a port to wait on, then it does not matter what type of port it is. If you want to handle errors, you might want to look at Ccr.Core.SuccessFailurePort which is a portset that returns a success result or a Fault.

    Trevor


    Saturday, August 8, 2009 1:42 AM
  • Hi,
    I'm trying to use CCR in my project and there are places that I want to "jump" into ccr code and wait sync until it done.
    I still get the benefit of doing things concurrently.

    I currently do that by "wrapping" the IterativeTask in my task which just yield the iterative task and when continue set a manual reset event like seen below.

    Is that a good way to do it or there are better ways?

        private void ExecuteToEnd(IterativeTask task) {
          var doneEvent = new System.Threading.ManualResetEvent(false);
          taskQueue.Enqueue(
            new IterativeTask<IterativeTask, System.Threading.ManualResetEvent>(
              task, doneEvent, ExecuteSingleTask)
          );
    
          doneEvent.WaitOne();
        }
    
        private IEnumerator<ITask> ExecuteSingleTask(
          IterativeTask task,
          System.Threading.ManualResetEvent doneEvent) {
    
          yield return task;
          doneEvent.Set();
        }
    
    Thank you,
    Ido.
    Thursday, February 25, 2010 10:31 AM
  • Hello Ido,

    This is the way I do it on my side and it works... Just make sure you never call your "ExecuteToEnd" from a CCR Thread because you could end up in a state where all your CCR threads are blocked, and this is quite bad.  Even worse, someone with 1 core would block indefinately as soon as the function is called.

    But if you are certain that your ExecuteToEnd method is only called outside the CCR context you are good to go.

    Luc
    Thursday, February 25, 2010 12:34 PM
  • Hi,
    Thanks for the answer.
    I found this thread which also talk about the same thing: http://social.msdn.microsoft.com/Forums/en-US/roboticsccr/thread/33167989-287b-4d5d-a079-07e3ac14034e/

    Ido.
    Thursday, February 25, 2010 4:30 PM