在前面中已经讲到了怎么在启动workflow时给它传递参数,可这在实际开发中往往是不够的,那我们该怎么在workflow运行的时候,怎样在宿主程序里与它交互呢,从宿主程序中给workflow传递数据,必须通过一个接口,而这个接口是被ExternalDataExchange修饰的,
新建一个workflow控制台应用程序SendMessage
我们先定义一个IMyService接口,如下:
using System.Workflow.Activities;//引入这个命名空间,不然会提示找不到ExternalDataExchange
[ExternalDataExchange]
public interface IMyService
{
event EventHandler<MessageArgs> Send;
}
聪明的读者,估计你已经注意到MessageArgs这个类了,这个类不是自带的,它里面的属性为我们要传递给workflow的属性,这个类如下:
[Serializable]
public class MessageArgs:ExternalDataEventArgs
{
private String msg;
public MessageArgs(Guid instanceId,String message)
: base(instanceId)
{
this.msg=message;
}
public String Msg
{
get { return msg; }
set { msg = value; }
}
}
注意:这个类要用Serializable,它要求是可序列化的,同样要引入System.Workflow.Activities命名空间
之后我们还要写一个类来实现一下这个接口,如下:
public class MyService:IMyService
{
public event EventHandler<MessageArgs> Send;
public void SendMessage(MessageArgs message)
{
EventHandler<MessageArgs> temp = this.Send;
if (temp != null)
{
temp(null, message);
}
}
}
MyService类中多了一个方法,在这个方法中我们触发了Send这个事件,下面要做的是在Workflow中怎样接收数据,双击workflow1.cs转到设计视图,从工具栏中拖一个HandleExternalEvent Activity(处理外部事件)到设计视图中去,如图所视:
看到右上面的感叹号没有,是因为有一些必设属性我们没有设置,在它的属性窗口中InterfaceType中指定接口为IMyService,操作为点击InterfaceType属性中的[..]按钮,在弹出窗口中选择,如图所示:
这时EventName上还有感叹号,我们为它指定一下事件名为Send(在下拉列表中选取即可)
当发生这个事件时,我们在workflow中指定的方法进行处理,同样在HandleExternalEvent1的属性Invoked中写入OutPutMessage,然后双周,程序自动生成OutPutMessage方法,并转到代码块,我们简单地处理一下,将接收到的信息打印出来,代码如下:
private void OutPutMessage(object sender, ExternalDataEventArgs e)
{
MessageArgs args = (MessageArgs)e;
Console.WriteLine(args.Msg);
}
现在我们基本上大功告成了,还要在宿主程序中注册一下这个类,双击program.cs转到代码,我把Main函数里的代码全贴出来了:
using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
ExternalDataExchangeService service = new ExternalDataExchangeService();
MyService myservice = new MyService();
workflowRuntime.AddService(service);
service.AddService(myservice);
AutoResetEvent waitHandle = new AutoResetEvent(false);
workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();};
workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
};
WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(SendMessage.Workflow1));
instance.Start();
myservice.SendMessage(new MessageArgs(instance.InstanceId,"Send Message to Workflow"));
waitHandle.WaitOne();
Console.WriteLine("Enter any key to exit...");
Console.ReadLine();
}
关键部分已用红色标记:
ExternalDataExchangeService service = new ExternalDataExchangeService();
MyService myservice = new MyService();
workflowRuntime.AddService(service);
service.AddService(myservice);
在workflow注册一下服务,再在服务中注册一个MyService实例,这样workflow就可以感应到这个事件了.
myservice.SendMessage(new MessageArgs(instance.InstanceId,"Send Message to Workflow"));
SendMessage方法触发Send方法,workflow中已经注册了监听,事件触发时,将Msg打印出来,
好了,按F5运行下,效果如下:
附件:我空间出了点问题,暂时传不上去,我会尽快将文件上传.