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(); } } } |
《WF本质论》中的第一章例子
转载于:https://www.cnblogs.com/kyorry/archive/2009/08/11/1544010.html