OpenSesame示例源码

《WF本质论》中的第一章例子


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();

        }

    }

}


posted @ 2009-08-11 23:15  rapid  阅读(404)  评论(2编辑  收藏  举报