Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pause during execution, save state, and continue from same point later on?

I have a thread that is doing some processing. I would like to be able to stop this thread during execution, somehow save it's position (and the state of the objects it is operating on), and then continue from that that location at a later date (so after my computer has restarted).

In C# this isn't possible right? And if not, what is the proper design to achieve this functionality?

So my original wish was to have something like

class Foo : Task {   
    void override   Execute(){ 
        //example task
        while(someCondition){
        ...do stuff... 
        }
    }
}

and be able to pause/save at any point within that function. When the function ends, everyone knows it is complete. As an alternative, perhaps this is the better way to do it

class Foo : Task {


    void override Execute(State previousState){
        //set someCondition, other stuff
        //IsPaused = false;
        previousState.setUpStuff();

        //example task
        while(someCondition){
            ...do stuff... 
            if(base.IsPauseRequested){
                 base.UpdateState(); //this would be a bit different but just to get the idea
                 base.IsPaused = true;
                 return;
            }
        }

        base.RaiseNotifyTaskComplete();
    }

}

So the first case is a lot simpler for other people who need to inherit my base class as they only have to implement the Execute function. However, in the second case, they have to consider the previous state and also manage where good pause points exist. Is there a better way to do this?

like image 709
i8abug Avatar asked Nov 03 '11 14:11

i8abug


2 Answers

What you want could be accomplished by a serializable state machine. Basically, you change your local variables into fields in a class and add a field that keeps the state – the position in the code of the original method. This class will be [Serializable] and it will have one method like MoveNext(), which does a piece of work and returns. When working, you call this method in a loop. When you want to stop, you wait until the current call finishes, break out of the loop and then serialize the state machine to the disk.

Based on the complexity of the original method and how often you do want to “checkpoint” (when the MoveNext() method returns and you can choose to continue or not), the state machine could be as simple as having just one state, or quite complicated.

The C# compiler does very similar transformation when it's compiling iterator blocks (and C# 5's async methods). But it's not meant for this purpose and it doesn't mark the generated class [Serializable], so I don't think you could use it. Although reading some articles about how this transformation is actually done might help you do the same yourself.

like image 95
svick Avatar answered Nov 05 '22 00:11

svick


This can be farily easily achieved using WF...it has all the plumbing to explicitly pause and resume tasks (and it takes care of the persistence for you). Check out this link.

Probably not be suitable for what you want, but maybe worth investigation.

like image 32
Mike Hanrahan Avatar answered Nov 05 '22 00:11

Mike Hanrahan