WF中顺序工作流本地通讯事件触发及调用步骤

Windows Workflow Foundation (WF)中顺序工作流是非常常用的一种工作流,而在工作流运行过程中通常会和宿主程序之间交换数据,用于从外部环境获取数据,同时将工作流的状态告诉外部环境。

工作流中用来达到此目的的activity有:WebServiceInput、WebServiceOutput、InvokeWebService、CallExternalMethod、HandleExternalEvent。前三个用于和WebServices交换数据,后两个用于本地的通讯。CallExternalMethod activity允许工作流来调用宿主中注册的程序,而HandleExternalEvent activity是让工作流通过宿主来监听对应的事件。

使用CallExternalMethod、HandleExternalEvent一般需要根据以下步骤:(以下借用《Programming Windows Workflow Foundation》中代码)

1、定义接口事件和相关的参数类型。

用ExternalDataExchange标签定义接口和事件。用Serializable标签定义参数类型。

    [ExternalDataExchange]
public interface IBugFlowService
{
event EventHandler<BugAddedArgs> BugAdded;
void AssignBug(Bug bug);
}
    [Serializable]
public class BugAddedArgs : ExternalDataEventArgs
{
private Bug _bug;

    <span class="kwrd">public</span> BugAddedArgs(Guid instanceId, Bug newBug):<span class="kwrd">base</span>(instanceId)
    {
        _bug = newBug;
    }

    <span class="kwrd">public</span> Bug NewBug
    {
        get
        {
            <span class="kwrd">return</span> _bug;
        }
        set
        {
            _bug = <span class="kwrd">value</span>;
        }
    }
}




2、定义传送的对象

这一步也可以放在之前或其他文件中,但对象必须打上Serializable标签。

    [Serializable]
public class Bug
{
private string _description;
private int _id;
private string _title;

    <span class="kwrd">public</span> Bug(<span class="kwrd">int</span> id, <span class="kwrd">string</span> title, <span class="kwrd">string</span> description)
    {
        _id=id;
        _title = title;
        _description = description;
    }

    <span class="kwrd">public</span> <span class="kwrd">string</span> Descrition
    {
        get { <span class="kwrd">return</span> _description; }
        set { _description = <span class="kwrd">value</span>;}
    }

    <span class="kwrd">public</span> <span class="kwrd">int</span> ID
    {
        get { <span class="kwrd">return</span> _id; }
        set { _id = <span class="kwrd">value</span>;}
    }

    <span class="kwrd">public</span> <span class="kwrd">string</span> Title
    {
        get {  <span class="kwrd">return</span> _title;}
        set{_title = <span class="kwrd">value</span>;}
    }
}</pre>

3、实现约定的接口

实现第一步中约定的服务接口

    public class BugFlowService : IBugFlowService
{
public event EventHandler<BugAddedArgs> BugAdded;

    <span class="kwrd">public</span> <span class="kwrd">void</span> AssignBug(Bug bug)
    {
        Console.WriteLine(<span class="str">"Assign '{0}' to developer"</span>, bug.Title);
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> CreateBug(Guid instanceID, Bug bug)
    {
        BugAddedArgs arg = <span class="kwrd">new</span> BugAddedArgs(instanceID, bug);
        EventHandler&lt;BugAddedArgs&gt; ev = <span class="kwrd">this</span>.BugAdded;
        <span class="kwrd">if</span> (ev != <span class="kwrd">null</span>)
        {
            ev(<span class="kwrd">null</span>, arg);
        }
    }
}

4、设计工作流及参数

新建一个顺序工作流,并依次从ToolsBox中拖放HandleExternalEvent activity、CallExternalMethod activity。分别命名NewBug、AssignBug。

设置命名为NewBug的HandleExternalEvent activity的InterfaceType属性为IBugFlowService,指定EventName属性为BugAdded,设置e参数来代表传入的事件参数,点击右侧的省略号按钮来绑定(或创建并绑定)参数到公开域或属性(例如:_newBug)。

设置命名为AssignBug的CallExternalMethod activity的InterfaceType属性为IBugFlowService,指定MethodName属性为AssignBug,AssignBug需要一个参数bug,点击bug参数右侧的省略号按钮来绑定(或创建并绑定)参数到公开域或属性(例如:_bugToAssign),为MethodInvoking事件生成事件处理方法AssignBug_MethodInvoking。

        public Bug _bugToAssign;
public BugAddedArgs _newBug;

<span class="kwrd">private</span> <span class="kwrd">void</span> AssignBug_MethodInvoking(<span class="kwrd">object</span> sender, EventArgs e)
{

    _bugToAssign = _newBug.NewBug;

}</pre>

5、在宿主中执行工作流

修改宿主启动工作流地方相关代码:

    ExternalDataExchangeService dataService;
dataService = new ExternalDataExchangeService();
workflowRuntime.AddService(dataService);
BugFlowService bugFlow = new BugFlowService();
dataService.AddService(bugFlow);

WorkflowInstance instance = workflowRuntime.CreateWorkflow(
                               <span class="kwrd">typeof</span>(wf_test1.chapter3_sequential));
instance.Start();

Bug bug = <span class="kwrd">new</span> Bug(1, <span class="str">"Bug Title"</span>, <span class="str">"Bug Description"</span>);
bugFlow.CreateBug(instance.InstanceId, bug);</pre>

 

注意事项说明:

1、接口必须打上ExternalDataExchange标签,才能使用工作流的数据交换服务[DataExchangeService]。

2、事件中参数类型必须继承自ExternalDataEventArgs类,参数类型必须打上Serializable标签。

3、事件句柄建议使用EventHandler<T>的方式,否则可能收到“The event BugAdded has to be of type EventHandler where T derives from ExternalDataEventArgs”的错误提示。

4、需要引用System.Workflow.Activities命名空间。