Eri*_*sch 4 c# oop refactoring request-cancelling
我有一个类是"经理"类.其中一个功能是发出应该关闭该类的长时间运行过程的信号.它通过在类中设置一个名为"IsStopping"的布尔值来实现.
public class Foo
{
bool isStoping
void DoWork() {
while (!isStopping)
{
// do work...
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,DoWork()是一个巨大的功能,我决定重构它,并且作为该过程的一部分,将其中的一部分打破到其他类中.问题是,这些类中的一些还具有长时间运行的函数,需要检查isStopping是否为真.
public class Foo
{
bool isStoping
void DoWork() {
while (!isStopping)
{
MoreWork mw = new MoreWork()
mw.DoMoreWork() // possibly long running
// do work...
}
}
}
Run Code Online (Sandbox Code Playgroud)
我有什么选择?
我已经考虑通过引用传递isStopping,我不喜欢它,因为它需要有一个外部对象.我宁愿让额外的课程尽可能独立和免费.
我还考虑过使用isStopping属性,然后让它调用一个内部类可以订阅的事件,但这看起来过于复杂.
另一种选择是创建一个"进程取消令牌"类,类似于.net 4 Tasks使用的类,然后将该令牌传递给这些类.
你是怎么处理这种情况的?
编辑:
还要考虑MoreWork可能有一个实例化的EvenMoreWork对象,并在...上调用可能长时间运行的方法.我想我正在寻找的是一种方法,能够在调用树下发出任意数量的对象信号,告诉他们停止他们正在做的事情并清理和返回.
EDIT2:
感谢到目前为止的回复.似乎对使用的方法没有真正的共识,每个人都有不同的意见.看起来这应该是一种设计模式......
你可以在这里走两条路:
1)您已经概述的解决方案:将信号机制传递给您的下级对象:bool(通过ref),父对象本身隐藏在接口中(Foo: IController在下面的示例中)或其他内容.子对象根据需要检查信号.
// Either in the MoreWork constructor
public MoreWork(IController controller) {
this.controller = controller;
}
// Or in DoMoreWork, depending on your preferences
public void DoMoreWork(IController controller) {
do {
// More work here
} while (!controller.IsStopping);
}
Run Code Online (Sandbox Code Playgroud)
2)转动它并使用观察者模式 - 这将允许您将下级对象与父项分离.如果我是手工完成(而不是使用事件),我会修改我的下级类来实现一个IStoppable接口,并让我的经理类告诉他们什么时候停止:
public interface IStoppable {
void Stop();
}
public class MoreWork: IStoppable {
bool isStopping = false;
public void Stop() { isStopping = true; }
public void DoMoreWork() {
do {
// More work here
} while (!isStopping);
}
}
Run Code Online (Sandbox Code Playgroud)
Foo 维护一个可停止的停止列表,并在其自己的停止方法中,将它们全部停止:
public void Stop() {
this.isStopping = true;
foreach(IStoppable stoppable in stoppables) {
stoppable.Stop();
}
}
Run Code Online (Sandbox Code Playgroud)