





























using System;
using System.Collections.Generic;
using System.Threading;
namespace OpenSesame
{
public delegate void BookmarkLocation(Bookmark resumed);
[Serializable]
public class Bookmark
{
public Bookmark(string name, BookmarkLocation continueAt)
{
Name = name;
ContinueAt = continueAt;
}
public string Name { get; set; }
public BookmarkLocation ContinueAt { get; set; }
public object Payload { get; set; }
public BookmarkManager BookmarkManager { get; set; }
}
public class BookmarkManager
{
private List<Bookmark> bookmarkList;
private ProgramStatement currentProgramStatement;
public BookmarkManager()
{
bookmarkList = new List<Bookmark>();
}
public void Add(Bookmark bookmark)
{
bookmarkList.Add(bookmark);
bookmark.BookmarkManager = this;
}
public void Remove(Bookmark bookmark)
{
bookmarkList.Remove(bookmark);
}
public void Resume(string bookmarkName, object payload)
{
foreach (Bookmark bookmark in bookmarkList)
{
if (bookmark.Name == bookmarkName)
{
bookmark.Payload = payload;
bookmark.ContinueAt(bookmark);
break;
}
}
}
// Request execution of a program statement, using an
// implicit bookmark that will be resumed when that
// program statement completes its execution
public void RunProgramStatement(ProgramStatement statement, BookmarkLocation continueAt)
{
currentProgramStatement = statement;
Bookmark bookmark = new Bookmark(statement.GetType().FullName, continueAt);
Add(bookmark);
statement.Run(this);
}
// Indicate that the current program statement is done,
// so that internally managed bookmarks can be resumed
public void Done(bool bAllDone)
{
if (!bAllDone)
Resume(currentProgramStatement.GetType().FullName, currentProgramStatement);
else
bookmarkList.Clear();
}
}
[Serializable]
public abstract class ProgramStatement
{
public abstract void Run(BookmarkManager mgr);
}
public class MythicalRuntime
{
Dictionary<ProgramHandle, ProgramStatement> ht;
private BookmarkManager mgr = new BookmarkManager();
public MythicalRuntime()
{
ht = new Dictionary<ProgramHandle, ProgramStatement>();
}
public BookmarkManager Mgr
{
get { return mgr; }
set { mgr = value; }
}
public ProgramHandle RunProgram(ProgramStatement program)
{
//这个新的Guid根据规则创建,而不是简单的new Guid(),以下仅为模拟方法
Guid programId = new Guid();
ProgramHandle programHandle = new ProgramHandle();
programHandle.ProgramId = programId;
ht.Add(programHandle, program);
//Bookmark的上半部分,用新的thread执行
ThreadPool.QueueUserWorkItem(state => program.Run(state as BookmarkManager), Mgr);
return programHandle;
}
public ProgramHandle GetProgramHandle(Guid programId)
{
//根据programId恢复已经钝化的程序,假设恢复为read方法
ProgramStatement program = new Read();
//重新构建ProgramHandle
ProgramHandle programHandle = new ProgramHandle();
programHandle.ProgramId = programId;
//重新加载到内存
ht.Add(programHandle, program);
return programHandle;
}
public void Shutdown()
{
//从内存中取出所有ProgramHandle, 依次钝化
foreach (ProgramHandle tmpProgramHandle in ht.Keys)
{
ProgramStatement program = ht[tmpProgramHandle];
tmpProgramHandle.Passivate(program);
}
ht = null;
}
}
public class ProgramHandle
{
private Guid programId;
public Guid ProgramId
{
get { return programId; }
set { programId = value; }
}
public void Passivate(ProgramStatement program)
{
//将program根据关键字programId进行钝化
}
public void Resume(string bookmarkName, object payload)
{
BookmarkManager mgr = new BookmarkManager();
mgr.Resume(bookmarkName, payload);
}
}
[Serializable]
public class Read : ProgramStatement
{
private string text;
public string Text
{
get { return text; }
}
public override void Run(BookmarkManager mgr)
{
mgr.Add(new Bookmark("read", ContinueAt));
}
void ContinueAt(Bookmark resumed)
{
text = (string)resumed.Payload;
BookmarkManager mgr = resumed.BookmarkManager;
mgr.Remove(resumed);
mgr.Done(false);
}
}
[Serializable]
public class PrintKey : ProgramStatement
{
private string key;
public string Key
{
get { return key; }
}
public override void Run(BookmarkManager mgr)
{
// Print the key
key = DateTime.Now.Millisecond.ToString();
Console.WriteLine("here is your key: " + key);
mgr.Done(false);
}
}
[Serializable]
public class PrintGreeting : ProgramStatement
{
private string key;
public string Key
{
get { return key; }
set { key = value; }
}
private string s;
public string Input
{
get { return s; }
set { s = value; }
}
public override void Run(BookmarkManager mgr)
{
//没有做特殊处理,key肯定是null.
if (string.IsNullOrEmpty(key))
{
Console.WriteLine("OKOK");
return;
}
// Print the greeting if the key is provided
if (key.Equals(s))
Console.WriteLine("hello, world");
else
{
Console.WriteLine("Wrong key!");
}
mgr.Done(false);
}
}
[Serializable]
public class ProgramStatementBlock : ProgramStatement
{
int currentIndex;
List<ProgramStatement> statements = new List<ProgramStatement>();
public IList<ProgramStatement> Statements
{
get { return statements; }
}
public override void Run(BookmarkManager mgr)
{
currentIndex = 0;
// Empty statement block
if (statements.Count == 0)
mgr.Done(true);
else
mgr.RunProgramStatement(statements[0], ContinueAt);
}
public void ContinueAt(Bookmark resumed)
{
BookmarkManager mgr = resumed.BookmarkManager;
// If we've run all the statements, we're done
if (++currentIndex == statements.Count)
mgr.Done(true);
else // Else, run the next statement
mgr.RunProgramStatement(statements[currentIndex], ContinueAt);
}
}
public class OpenSesame_v3
{
static void Main(string[] args)
{
ProgramStatementBlock openSesameProgram = new ProgramStatementBlock();
PrintKey printKey = new PrintKey();
Read read = new Read();
PrintGreeting printGreeting = new PrintGreeting();
printGreeting.Key = printKey.Key;
printGreeting.Input = read.Text;
openSesameProgram.Statements.Add(printKey);
openSesameProgram.Statements.Add(read);
openSesameProgram.Statements.Add(printGreeting);
MythicalRuntime runtime = new MythicalRuntime();
ProgramHandle handle = runtime.RunProgram(openSesameProgram);
string s = Console.ReadLine();
//Bookmark的下半部分,用新的thread执行
ThreadPool.QueueUserWorkItem(state => runtime.Mgr.Resume("read", state), s);
// keep the main thread running
Console.ReadLine();
}
}
}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。