工作流和宿主应用程序交流

其实和工作流的交互我前面已经有个文字了。就是这个:给WWF传递参数
这个文章主要说的就是第二中情况。事件和方法,是指工作流添加activity的事件来接受和传递参数
。这里面有两个很重要的活动CallExternalMethodActivityHandleExternalEvent
前者是调用方法,后者是调用事件。其中宿主应用程序调用事件,工作流调用方法。这个两个是基本的概念。
事件只有两个参数,一个是sender谁触发的,一个是相关的参数。这是固定。
先说这些基本概念,然后说一个具体例子。这个例子运行一个工作流,然后先开始投票这个工作。然后要给一个人投票,支持或者反对这是两个事件。
&<60;&<60;&<60; 新建顺序工作流控制台项目。添加window.form引用。打开program文件,里面已经有了代码。使用这个代码当然也可以。也可以使用这个代码,和原来的代码基本相同,就是添加了。工作流引擎创建和结束的事件输出而已
class Program
 {
 static AutoResetEvent waitHandle = new AutoResetEvent(false);
 static VotingService votingService;

 static void Main(string[] args)
 {
 WorkflowRuntime workflowRuntime = new WorkflowRuntime();

ExternalDataExchangeService dataService = new ExternalDataExchangeService();
workflowRuntime.AddService(dataService);
 votingService = new VotingService();
dataService.AddService(votingService);

workflowRuntime.WorkflowCreated += new EventHandler<WorkflowEventArgs>(workflowRuntime_WorkflowCreated);
workflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(workflowRuntime_WorkflowCompleted);

 Type type = typeof(Workflow1);
 workflowRuntime.CreateWorkflow(type).Start();

 waitHandle.WaitOne();
Console.WriteLine("Press any key to exit...");
 Console.Read();
 }

static void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
 {
Console.WriteLine("Workflow " + e.WorkflowInstance.InstanceId.ToString() + " completed.");
waitHandle.Set();
}

static void workflowRuntime_WorkflowCreated(object sender, WorkflowEventArgs e)
 {
Console.WriteLine("Workflow " + e.WorkflowInstance.InstanceId.ToString() + " created.");
 }
}

 ExternalDataExchangeService dataService = new ExternalDataExchangeService();
workflowRuntime.AddService(dataService);
 votingService = new VotingService();
 dataService.AddService(votingService);
注意这段话,使用交互必须添加这个服务,
VotingService就是将要使用的服务类。
这里要说明的服务类的格式是基本固定。一个接口。接口中定义事件和方法,一个参数类继承ExternalDataEventArgs而且要实现序列化,然后就是实现类他继承接口。

类文件如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Workflow.Activities;
using System.Windows.Forms;
using System.Threading;
using System.Workflow.Runtime;

namespace Communition2_25
{
 [Serializable]
public class VotingEventArgs : ExternalDataEventArgs//参数类
 {
 private string alias;

public VotingEventArgs(Guid InstanceID, string alias)
 : base(InstanceID)
{
 this.alias = alias;
 }

public string Alias
 {
 get { return this.alias; }
set { this.alias = value; }
 }
 }

 [ExternalDataExchange]
 internal interface IVotingService//接口定义事件和方法。宿主触发事件,工作流使用方法
 {
 event EventHandler<VotingEventArgs> ApproveProposal;
event EventHandler<VotingEventArgs> RejectProposal;

void CreateBallot(string alias);
}

internalclass VotingService : IVotingService
 {
public event EventHandler<VotingEventArgs> ApproveProposal;
public event EventHandler<VotingEventArgs> RejectProposal;

public void CreateBallot(string alias)//
 {
Console.WriteLine("Ballot created for " + alias + ".");
 ThreadPool.QueueUserWorkItem(ShowVotingDialog, new VotingEventArgs(WorkflowEnvironment.WorkflowInstanceId, alias));
}

 public void ShowVotingDialog(object o)
 {
DialogResult result;
 VotingEventArgs votingEventArgs = o as VotingEventArgs;
 Guid instanceId = votingEventArgs.InstanceId;
 string alias = votingEventArgs.Alias;

 result = MessageBox.Show("Approve Proposal, " + alias + "?", alias + " Ballot", MessageBoxButtons.YesNo);
 if (result == DialogResult.Yes)
 {
if (ApproveProposal != null)
ApproveProposal(null, votingEventArgs);
 }
 else
{
if (RejectProposal != null)
 RejectProposal(null, votingEventArgs);
 }
}
 }

}
然后打开workflow文件的设计视图:添加
CallExternalMethodActivity .设置他的几个必须属性
接口和方法,打开选择框可以看到我们已经定义好的接口
IVotingService,然后选择方法CreateBallot。这是这个方法有个参数alias在面板中设置Jim。这个活动就设置完毕了。
然后我们添加一个listen活动。这个listen活动是有两个以上的事件活动组成的。他的特点是只要其中一个事件执行那么整个listen就算完成了。
我们托两个
HandleExternalEvent分别放到左支和右支。左侧那个改名字Approve右侧改名Reject表示一个引发支持事件一个引发反对事件。点击Arrpove活动设置他的属性其中接口和事件名称是必须。选择IVotingService接口,和ApproveProposal事件。Reject活动同样处理只是他引发RejectProposal事件。此外还有设置当这个事件引发后调用什么方法,点击approve活动其中有个属性Invoked设置OnApproved。我们在后台文件中 添加这个方法就行了。
private void OnApproved(object sender, ExternalDataEventArgs e)
 {
 Console.WriteLine("Proposal Approved :" + votingArgs.Alias);
}
Reject活动相同设置
private void OnRejected(object sender, ExternalDataEventArgs e)
 {
 Console.WriteLine("Proposal Rejected : " + votingArgs.Alias);
 }
这个地方有个要说明的地方。点击事件活动的时候下面有两个参数一个e和一个sender。他们提供了把e参数,就是我们事件中定义的e这个参数绑定给一个字段或属性的功能。我们选择绑定给一个新的成员,然后选择属性输入名称votingArgs,最后点击确定,这样工作流文件中多了这样一个属性
public static DependencyProperty votingArgsProperty = DependencyProperty.Register("votingArgs", typeof(Communition2_25.VotingEventArgs), typeof(Communition2_25.Workflow1));

 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
 [BrowsableAttribute(true)]
 [CategoryAttribute("Parameters")]
 public VotingEventArgs votingArgs
 {
 get
 {
 return ((Communition2_25.VotingEventArgs)(base.GetValue(Communition2_25.Workflow1.votingArgsProperty)));
 }
 set
 {
 base.SetValue(Communition2_25.Workflow1.votingArgsProperty, value);
 }
 }
这样我们在触发支持事件后的OnApproved方法中就可以得到事件参数。就是alias。
private void OnApproved(object sender, ExternalDataEventArgs e)
 Console.WriteLine("Proposal Approved :" + votingArgs.Alias);
 }
这样这个工作流就完成了。
编译运行就ok

本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。

原文地址:https://www.cnblogs.com/zjypp/p/2319436.html