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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With