[转帖]ACTIVE OBJECT 模式
我们可以对该程序和等待一个事件的多线程程序做一个类比。当多线程程序中的一个线程等待一个事件时,它通常使用一些操作系统调用来阻塞自己知道事件发生。代码清单1-4中的程序并没有阻塞。相反,如果所等待的(elapsedTime.TotalMilliseconds < SleepTime)这个事件没有发生,线程只是把自己放回到 ActiveObjectEngine 中。
采用该技术的变体去构建多线程系统已经是并且将会一直是一个常见的实践。这种类型的线程成为 run-to-completion 任务(RTC),因为每个 Command 实例在下一个 Command 实例可以运行之前就运行完成了。RTC 的名字意味着 Command 实例不会阻塞。
Command 实例一经运行就一定得完成的特性赋予了RTC线程有趣的优点,那就是它们共享同一个运行栈。和传统的多线程系统的线程不通,不必为每个RTC线程定义或者分配各自的运行时栈。这在需要大量线程的内存受限系统中是一个强大的优势。
继续我们的例子,代码清单1-5展示了一个简单的程序,其中使用了SleepCommand 并展示了它的多线程行为。该程序成为 DelayedType 。
代码清单1-5
using System;
using System.Collections.Generic;
using System.Text;
namespace ActiveObject
{
public class DelayedTyper : ICommand
{
private long itsDelay;
private char itsChar;
private static bool stop = false;
private static ActiveObjectEngine engin =
new ActiveObjectEngine();
private class StopCommand : ICommand
{
public void Execute()
{
DelayedTyper.stop = true;
}
}
public static void
{
engin.AddCommand(new DelayedTyper(100, ’A’));
engin.AddCommand(new DelayedTyper(300, ’B’));
engin.AddCommand(new DelayedTyper(500, ’C’));
engin.AddCommand(new DelayedTyper(700, ’D’));
ICommand stopCommand = new StopCommand();
engin.AddCommand(new SleepCommand(2000, engin, stopCommand));
engin.Run();
Console.ReadLine();
}
public DelayedTyper(long delay, char c)
{
this.itsDelay = delay;
this.itsChar = c;
}
public void Execute()
{
Console.Write(itsChar);
if (!stop)
{
DelayAndRepeat();
}
}
private void DelayAndRepeat()
{
engin.AddCommand(new SleepCommand(itsDelay, engin, this));
}
}
}
请注意 DelayedType 实现了 ICommand 接口。 它的 execute 方法只是打印出在构造时传入的字符,检查 stop 标志,并在该标志没有被设置时调用 DelayAndRepeat。DelayAndRepeat 方法使用构造时传入的延迟构造了一个 SleepCommand 对象。难后把构造后的 SleepCommand 对象插入到 ActiveObjectEngine 中。
该ICommand 对象的行为很容易预测。实际上,它维持着一个循环,在循环中重复地打印一个指定的字符并等待一个指定的延迟。当 stop 标志被设置时,就退出循环。
DelayedTyper 的 Main 函数创建了一个 SleepCommand 对象,该对象会在一段时间后设置 stop 标志。运行该程序会打印出一个简单的由 A、B、C、D 组成的字符串。运行结果:
ABCDAABAACABADAABACAABADACABAAABACADB
转自:
http://www.cnblogs.com/bruceleeliya/archive/