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

Dominic