none
Best way to return value from an iterator RRS feed

  • Question

  • Hi All,

    I have an iterator Iterator2 that I would like to synchronously execute from another iterator Iterator1. If there is an error executing Iterator2, i want it to be returned to Iterator1 after Iterator2 is done executing. I was thinking of passing an object of Exception class to the iterator as an "out" parameter but then realized that it is not possible. So, I am trying to find out what would be the best way to do this. I have the following possible solutions. Please let me know what you think of them and also if there is any other better way to do it.

    Solution 1

    Pass a success failure port and wait for the iterator to complete execution and then check the success failure port whether the result is a success or failure.

    private IEnumerator<ITask> Iterator1()
    {
        var successFailurePort = new SuccessFailurePort();
        yield return new IterativeTask<SuccessFailurePort>(successFailurePort, Iterator2);
        Exception e = successFailurePort;
        if(e != null)
        {
            // Do Something
            yield break;
        }
    }
    
    private IEnumerator<ITask> Iterator2(SuccessFailurePort successFailurePort)
    {
        successFailurePort.Post(new Exception("Some Exception"));
        yield break;
    }

    Solution 2

    Pass a success failure port and wait for a message in the success failure port

    private IEnumerator<ITask> Iterator1()
    {
        var successFailurePort = new SuccessFailurePort();
        Arbiter.ExecuteToCompletion(TaskQueue, new IterativeTask<SuccessFailurePort>(successFailurePort, Iterator2));
        yield return Arbiter.Choice(successFailurePort);
        Exception e = successFailurePort;
        if(e != null)
        {
            // Do Something
            yield break;
        }
    }
    
    private IEnumerator<ITask> Iterator2(SuccessFailurePort successFailurePort)
    {
        successFailurePort.Post(new Exception("Some Exception"));
        yield break;
    }

    Solution 3

    Write a wrapper class having an Exception object and pass on an object of that class.

    class  ExceptionWrapper
    {
        public Exception Exception { get; set; }
    }
            
    private IEnumerator<ITask> Iterator1()
    {
        var exceptionWrapper = new ExceptionWrapper();
        yield return new IterativeTask<ExceptionWrapper>(exceptionWrapper, Iterator2);
        if(exceptionWrapper.Exception != null)
        {
            // Do Something
            yield break;
        }
    }
    
    private IEnumerator<ITask> Iterator2(ExceptionWrapper exceptionWrapper)
    {
        exceptionWrapper.Exception = new Exception("Some Exception");
        yield break;
    }

    Thanks,

    Venkat

    Friday, November 30, 2012 4:44 AM
    Moderator

Answers

  • Have you tried these?  Do they work?

    I am not an expert, but I have some thoughts...

    1) These iterators are running synchronously.  If you check e right away then it may not have been set yet and you will miss the exception.

    2) Won't ExecuteToCompletion make this behave synchronously...  not what you said you wanted.

    3) I think this might have the same issue as #1

    Sounds like you want both synchronous and asynchronous behavior, but you have to choose.  Either they are executing simultaneously and you have no idea when the exception may occur, or you serialize them and you can know if something has happened before you proceed.

    I think you may want to back up and re-think the design and purpose of what you are trying to accomplish.

    -G

    Thursday, December 6, 2012 5:17 AM

All replies

  • Have you tried these?  Do they work?

    I am not an expert, but I have some thoughts...

    1) These iterators are running synchronously.  If you check e right away then it may not have been set yet and you will miss the exception.

    2) Won't ExecuteToCompletion make this behave synchronously...  not what you said you wanted.

    3) I think this might have the same issue as #1

    Sounds like you want both synchronous and asynchronous behavior, but you have to choose.  Either they are executing simultaneously and you have no idea when the exception may occur, or you serialize them and you can know if something has happened before you proceed.

    I think you may want to back up and re-think the design and purpose of what you are trying to accomplish.

    -G

    Thursday, December 6, 2012 5:17 AM
  • Hi Gershon,

    Thank you for your time and reply. I actually want them to execute synchronously. In particular, I want Iterator2 to be executed synchronously from Iterator1.

    1) Since, I do an yield return on the Choice on the SuccessFailure port, it will only pass through once there is a message in either of the Success or the Failure ports.

    2) I believe that only when you do a yield return on ExecuteToCompletion, it is synchronous, else it executes asynchronously.

    3) Since, we are doing a yield return, it will be synchronous.

    Please clarify.

    Thanks,

    Venkat

    Friday, December 7, 2012 4:05 AM
    Moderator
  • Are these iterators in the same class? 
    Since you are having them run synchronously, could you just set a field in the class with the exception information and check it when its done?
    Does it really need to be another iterator?  Could you just do the work in that first iterator?
    Without trying each of these and seeing how they work for me, I really can't advise you. 

    Monday, December 10, 2012 5:19 PM
  • Hi Gershon,

    Thank you for your time and reply. The reason why Iterator2 is an iterator is because I expect that to be supplied by the user to me and I expect the user some set of "yield return" so that they dont block the thread. Basically, Iteraor1 is an iterator because Iterator2 is an iterator. From what I understand of iterators, if you have an iterator deep down, all your parents who call this iterator and wait for it to complete should also be iterators, else you would have to write code that thread blocking code.

    Thanks,

    Venkat

    Wednesday, December 12, 2012 6:34 AM
    Moderator
  • OK.  So can we mark this thread answered now?  I think you just need to experiment and find what works for you.
    Friday, December 14, 2012 11:23 PM
  • I agree with you Gershon. Please mark whichever post you think would best fit as answered and I will confirm the same.
    Saturday, December 15, 2012 1:15 AM
    Moderator