C# 如何在执行过程中暂停、保存状态并在以后从同一点继续?

C# 如何在执行过程中暂停、保存状态并在以后从同一点继续?,c#,design-patterns,C#,Design Patterns,我有一个线程正在进行一些处理。我希望能够在执行期间停止该线程,以某种方式保存它的位置(以及它正在操作的对象的状态),然后在以后的某个日期从该位置继续(因此在我的计算机重新启动之后) 在C#中,这是不可能的,对吗?如果没有,实现此功能的正确设计是什么 所以我最初的愿望是要有 class Foo : Task { void override Execute(){ //example task while(someCondition){

我有一个线程正在进行一些处理。我希望能够在执行期间停止该线程,以某种方式保存它的位置(以及它正在操作的对象的状态),然后在以后的某个日期从该位置继续(因此在我的计算机重新启动之后)

在C#中,这是不可能的,对吗?如果没有,实现此功能的正确设计是什么

所以我最初的愿望是要有

class Foo : Task {   
    void override   Execute(){ 
        //example task
        while(someCondition){
        ...do stuff... 
        }
    }
}
并且能够在该功能内的任何点暂停/保存。当函数结束时,每个人都知道它已完成。 作为替代方案,也许这是更好的方法

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();
    }

}

因此,对于其他需要继承我的基类的人来说,第一种情况要简单得多,因为他们只需要实现Execute函数。然而,在第二种情况下,他们必须考虑先前的状态,并且管理好的暂停点存在的位置。有更好的方法吗?

我不能回答
C#
,但一般来说,这个问题是被调用的,没有简单的方法来解决它(除非语言和操作系统提供)。您不能根据一个线程进行推理,因为您正在考虑的线程正在引用一些其他(全局或堆)数据。这个问题也与(因为垃圾收集器和持久性机制都倾向于扫描整个活动堆)和(特别是那些)有关。因此,请阅读上的内容和教科书,也可查看网站,如

另请参阅报告,阅读Queinnec的书,并研究现有持久化软件的源代码,包括(当然还有C#的开源实现)

当您想要在的上下文中持久化的网络(或图形)时,事情变得更具挑战性。然后在网上搜索


在概念层面上,你的问题与一个主题相关,你可以在这个主题上找到许多赞助的会议(例如),

你可以通过表达式树或方法链来设置类似的内容。为不可中断的最小“原子”工作单元设置lambda或小方法。然后,用一个“主管”将它们链接在一起,该主管将按顺序执行每个块,但可以告诉它停止在指令之间执行的操作,保存其在链中的位置,返回并等待恢复。如果需要模式的名称,可以将其称为Visitor上的变体。

您希望在进程暂停时序列化对象的状态,然后在它重新启动时反序列化它

一个非常简单的实现是在任务类Serialize/Deserialize上创建两个静态方法,它们使用Linq在XML中读取/写入对象的状态。当任务暂停时,调用Serialize将对象作为xml转储到磁盘,当任务重新启动时,调用Deserialize读取xml。还有一个类可能更健壮


无论如何,这是一个复杂的问题,有一个概念上简单的解决方案。

您想要的可以通过一个可序列化的状态机来实现。基本上,您将局部变量更改为类中的字段,并添加一个保持状态的字段,即原始方法在代码中的位置。这个类将是
[Serializable]
,它将有一个类似
MoveNext()
的方法,它执行一项工作并返回。工作时,在循环中调用此方法。如果要停止,请等待当前调用完成,中断循环,然后将状态机序列化到磁盘

根据原始方法的复杂性以及您希望“检查点”的频率(当
MoveNext()
方法返回并且您可以选择继续或不继续时),状态机可以简单到只有一个状态,也可以相当复杂


C#编译器在编译迭代器块(以及C#5的
async
方法)时会进行非常类似的转换。但是它不是为了这个目的,也没有标记生成的类
[Serializable]
,所以我认为您不能使用它。尽管阅读一些关于如何实际完成此转换的文章可能会帮助您自己完成同样的工作。

这可以通过WF轻松实现……它有所有的管道来显式暂停和恢复任务(并为您提供持久性)


可能不适合您想要的,但可能值得研究。

这是一个很好的想法,我想知道这样的事情……几乎像一个充满函数指针(委托)的数组。所以我只是沿着数组移动一个指针。我的问题是我希望我的基类被其他人使用。我认为这样做会使情况过于复杂(因为许多人的任务在数组中只有一个函数指针)。不过我喜欢这个想法。听起来你基本上支持我用IsPaused变量的方法,对吗?我没有考虑太多我将如何连载,但可能像你说的那样。我希望有更好的方法来完成,但也许这种方法是处理这种情况的标准方法。不管怎样,如果你想暂停对象状态,你需要保存它,然后再回来。因此,是的,当您暂停并反序列化调用“setupStuff”的位置时,您将进行序列化