如果没有微软的WF,如何设计一个自己的工作流,本章通过经典的芝麻开门(OpenSesame)示例,向读者展示了WF基本的设计思路.
这一章我读了很多遍才想明白.建议所有读者在阅读后续章节时,一定要先读懂本章,这是全书的基石;还有就是本章的示例代码并不完整,仅仅是一个类及其方法的骨架,也是容易使人困惑的.

设计交互式WF,要解决两个问题:
    1.线程阻塞,比如说Console.ReadLine这样的语句, 因此有必要将其设计为异步方法BeginReadLine与EndReadLine,如下:

WF本质论 读书心得 1 剖析WF (上)    public static System.IAsyncResult BeginReadLine(System.AsyncCallback asyncCallback, object state);
WF本质论 读书心得 1 剖析WF (上)    
WF本质论 读书心得 1 剖析WF (上)    
public static string EndReadLine(System.IAsyncResult ar);

        使用如下, 注意到变量key实现了跨线程共享:

WF本质论 读书心得 1 剖析WF (上)        static string key;
WF本质论 读书心得 1 剖析WF (上)
WF本质论 读书心得 1 剖析WF (上)        
public static void Main()
        }

         不仅仅是ReadLine方法,所有阻塞线程的方法都可以一拆为二,并按照上述原则进行操作

    2.进程闲置
        闲置的进程可以序列化到外部,这个技术称为钝化passivate;需要的时候再进行恢复,恢复点称为书签Bookmark,程序上表现为delegate.
        钝化可以彻底消除对栈的依赖.
        Bookmark实体类设计如下:
WF本质论 读书心得 1 剖析WF (上)
注意, Name是key, Payload是异步调用时需要的参数,BookmarkLocation是一个委托,BookmarkManager用于指定当前Bookmark的管理器.

BookmarkManager是一个书签管理器,具体实现如下(书中省略了):

WF本质论 读书心得 1 剖析WF (上)    public class BookmarkManager
    }

对于逻辑类OpenSesame的实现,要求有一个全局变量key和一个异步方法ContinueAt,这是为了解决线程阻塞,上文已经述及其意图;此外Start()方法也是必须的,用于初始化书签管理器并将自身加入其中,最后这个类还要标明[Serializable]

于是Main()方法的实现如下:

WF本质论 读书心得 1 剖析WF (上)        static void Main(string[] args)
        }

至此,一个WF Sample完美实现,仅包括一个Sesame逻辑的一个实例。

接下来要考虑多个逻辑多个实例的实现:使用运行时Runtime进行管理
于是建立ProgramStatement抽象基类,所有逻辑类(如OpenSesame)都派生于此,其中Run()方法就是OpenSesame的Start()方法。我们称之为可恢复语句组件。
同时,建立MythicalRuntime类和PrograHandle类,进行更高层次的包装。
WF本质论 读书心得 1 剖析WF (上)
从而,Main()方法的实现可以如下:

WF本质论 读书心得 1 剖析WF (上)            MythicalRuntime runtime = new MythicalRuntime();
WF本质论 读书心得 1 剖析WF (上)
WF本质论 读书心得 1 剖析WF (上)            
while (true)
            }

注意,这段代码的功能仅仅是根据input进行恢复,并没有事先设置初始值,我们只要看清大致思路即可。
MythicalRuntime类和ProgramHandle类,书中省略了代码,我自己的实现如下:

WF本质论 读书心得 1 剖析WF (上)    public class MythicalRuntime
    }

根据我的理解,做出如下修正:
1.在MythicalRuntime类中添加泛型ht,建立了ProgramHandle与ProgramStatement的一一映射。
2.RunProgram专门用于在内存中创建新程序。
3.ProgramHandle类的Passivate()方法,增加方法参数后为:
    public void passive(ProgramStatement program);
    从而将programId和相应的ProgramStatement一起存储。


*本章的页眉都写错了,应该把"部"改为"剖",建议译者下一版时修正.

相关文章:

  • 2021-09-05
  • 2021-09-17
  • 2021-07-29
  • 2022-12-23
  • 2022-12-23
  • 2021-10-22
  • 2021-10-24
  • 2021-09-11
猜你喜欢
  • 2021-06-30
  • 2021-06-22
  • 2021-10-31
  • 2021-07-08
  • 2021-11-17
  • 2021-08-15
  • 2022-03-02
相关资源
相似解决方案