ActiveObject模式使用Command模式实现多线程do
2023-07-10 本文已影响0人
ljt001
参考 《敏捷软件开发 原则、模式与实践》P.141.
原文为java代码,此处为C#代码。
ActiveObject模式是使用Command模式实现多线程的一种古老技术。
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
public interface Command
{
void Execute();
}
public class ActiveObjectEngine
{
List<Command> commands = new List<Command>();
public void AddCommand(Command command)
{
commands.Add(command);
}
public void Run()
{
while (commands.Any())
{
var command = commands.First();
commands.Remove(command);
command.Execute();
}
}
}
public class SleepCommand : Command
{
private readonly long sleepMs;
private ActiveObjectEngine engine;
private Command wakeupCommand;
private bool started = false;
private DateTime startTime = DateTime.MinValue;
public SleepCommand(long sleepMs, ActiveObjectEngine engine, Command wakeupCommand)
{
this.sleepMs = sleepMs;
this.engine = engine;
this.wakeupCommand = wakeupCommand;
}
public void Execute()
{
var currentTime = DateTime.Now;
if (!started)
{
started = true;
startTime = currentTime;
engine.AddCommand(this);
}
else if ((currentTime - startTime).TotalMilliseconds < sleepMs)
{
engine.AddCommand(this);
}
else
{
//Console.Write("-");
engine.AddCommand(wakeupCommand);
}
}
}
public class DelayTyper : Command
{
private long delayMs;
private char itsChar;
private static bool stop = false;
private static ActiveObjectEngine engine = new ActiveObjectEngine();
static void Main(string[] args)
{
var stopCommand = new StopCommand();
engine.AddCommand(new DelayTyper(100, '1'));
engine.AddCommand(new DelayTyper(300, '3'));
engine.AddCommand(new DelayTyper(500, '5'));
engine.AddCommand(new DelayTyper(700, '7'));
engine.AddCommand(new SleepCommand(20000, engine, stopCommand));
engine.Run();
}
private class StopCommand : Command
{
public void Execute()
{
stop = true;
}
}
public DelayTyper(long delayMs, char itsChar)
{
this.delayMs = delayMs;
this.itsChar = itsChar;
}
public void Execute()
{
Console.Write(itsChar);
if (!stop)
{
DelayAndRepeat();
}
}
private void DelayAndRepeat()
{
engine.AddCommand(new SleepCommand(delayMs, engine, this));
}
}
}
输出结果示例
1357113115131711315113117153111311517311131511317115311131175131113151173111531113171513111315171311153111731151311131751131115311713115131117315113111531711311513117131511311175311131151317113151131171531113115173111315113171153111311751311131511731115311131715131113151713111531117311513111317511311153117131151311173151131115317113115137