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

工作流中用来达到此目的的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;

        public BugAddedArgs(Guid instanceId, Bug newBug):base(instanceId)
        {
            _bug = newBug;
        }

        public Bug NewBug
        {
            get
            {
                return _bug;
            }
            set
            {
                _bug = value;
            }
        }
    }


2、定义传送的对象

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

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

        public Bug(int id, string title, string description)
        {
            _id=id;
            _title = title;
            _description = description;
        }

        public string Descrition
        {
            get { return _description; }
            set { _description = value;}
        }

        public int ID
        {
            get { return _id; }
            set { _id = value;}
        }

        public string Title
        {
            get {  return _title;}
            set{_title = value;}
        }
    }

3、实现约定的接口

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

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

        public void AssignBug(Bug bug)
        {
            Console.WriteLine("Assign '{0}' to developer", bug.Title);
        }

        public void CreateBug(Guid instanceID, Bug bug)
        {
            BugAddedArgs arg = new BugAddedArgs(instanceID, bug);
            EventHandler<BugAddedArgs> ev = this.BugAdded;
            if (ev != null)
            {
                ev(null, 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;

        private void AssignBug_MethodInvoking(object sender, EventArgs e)
        {

            _bugToAssign = _newBug.NewBug;

        }

5、在宿主中执行工作流

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

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

    WorkflowInstance instance = workflowRuntime.CreateWorkflow(                                   typeof(wf_test1.chapter3_sequential));
    instance.Start();

    Bug bug = new Bug(1, "Bug Title", "Bug Description");
    bugFlow.CreateBug(instance.InstanceId, bug);

 

注意事项说明:

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命名空间。