WF4.0中书签是一个看似简单实际上是一个非常有用的功能,灵活的运用书签能实现很多不同的功能。本篇就介绍如何利用书签实现一个主流程动态调用子流程。
首先介绍一下,主流程与子流程的调用关系,如下图:
当主流程发起后,流传到调用子流程节点后,发起子流程。此时流程将在子流程中流程,直至子流程结束后重新流转至主流程。
本文的思路是利用书签,在进入调用子流程节点时,给主流程创建一个书签,让主流程暂停。同时发起另外一个子流程,并将书签的名称作为输入参数传入子流程中。当子流程结束时,利用被输入的书签名称释放主流程的书签,此时子流程结束,主流程恢复进行流转。
下面我们就来实现这个例子,先创建一个名为BookMark3的控制台WorkFlow工程,随后创建一个名为ChildStart的自定义活动,用它来调用子流程,代码如下:
public sealed class ChildStart : NativeActivity
{
// 定义一个字符串类型的活动输入参数
public InArgument<string> Text { get; set; }
/// <summary>
/// 重写这个方法,以便返回true值,true用来控制工作流闲置,可以挂起
/// 默认的情况为false,表示工作流不会挂起执行,因此用户无法和工作流之间进///行交互
/// </summary>
protected override bool CanInduceIdle
{
get
{ return true; }
}
// 如果活动返回值,则从 CodeActivity<TResult> http://
// 派生并从 Execute 方法返回该值。
protected override void Execute(NativeActivityContext context)
{
// 获取 Text 输入参数的运行时值
string text = context.GetValue(this.Text);
string strguid = Guid.NewGuid().ToString();
//创建书签
context.CreateBookmark(strguid, new BookmarkCallback(Continue));
Dictionary<string,object> param = new Dictionary<string,object>();
param.Add("BookMark", strguid);
WorkflowApplication wa = new WorkflowApplication(new ChildWF(),param);
wa.Run();
}
//书签恢复后调用的函数
void Continue(NativeActivityContext context, Bookmark bookmark, object obj)
{
}
}
在Execute函数内,首先创建了一个书签,书签名字为Guid(唯一吗)的字符型,随后利用WorkflowApplication发起了一个ChildWF类型的流程,并把 书签名称作为参数输入该流程。
再创建一个名为ChildEnd的自定义流程 ,用它作为子流程的结束节点,代码如下:
public sealed class ChildEnd : NativeActivity
{
// 定义一个字符串类型的活动输入参数
public InArgument<string> BookMark { get; set; }
// 如果活动返回值,则从 CodeActivity<TResult>
// 派生并从 Execute 方法返回该值。
protected override void Execute(NativeActivityContext context)
{
// 获取 Text 输入参数的运行时值
string StrBookMark = context.GetValue(this.BookMark);
Program.wa.ResumeBookmark(StrBookMark, null);
}
}
在该活动中有一个名为BookMark的输入参数,实际上,子流程将书签的名称传递给了该活动(如何传递看下面介绍),然后该活动利用传入的书签名称,将主流程对应的WorkflowApplication(这里是全局对象)恢复书签,从而让主流程继续执行下去。
完成好自定义活动后,我们来实现主流程的设计,主流程如下图:
其中节点ChildStart是用来发起子流程的。
子流程的设计如下图:
其中ChildEnd节点是用于在子流程结束时恢复主流程的运行,另外我们还增加了一个Delay节点,用来延时10秒,这样我们能看清流程的运行过程,避免一闪而过。
前面提到需要把书签作为参数输入子流程,因此我们还有两步操作
第一步,在流程中建立名为BookMark的输入参数变量,如下图:
第二步,我们还要把这个参数传入ChildEnd节点,ChildEnd节点有一个自定义的属性,名为BookMark。
我们在对应的值中输入BookMark,意味着该属性与流程的输入参数BookMark绑定了。
最后,我们完成主函数代码,代码如下:
class Program
{
public static WorkflowApplication wa;
static void Main(string[] args)
{
wa = new WorkflowApplication(new Workflow1());
wa.Run();
Console.Read();
}
}
就此我们的例子就完成了,运行该工程,执行后的结果如下图:
下一篇,我将开始介绍新的一部分内容,如何实现WF4.0的持久化 。