WF-Activities之HandleExternalEvent Activity

  工作流不是与外部隔离存在的,它也需要从外部环境接收数据,同时将自己的一些状态告诉外部环境,工作流中用来达到此目的的activity有:webserviceinput \webserviceoutput\ invokewebservice.

而对于本地的通讯,我们有CallExternalMethod activity 和 HandleExternalEvent activity。前者允许工作流来调用宿主中注册的程序,而后者是让工作流通过宿主来监听对应的事件。

 那么,事件是怎么传入工作流的呢,很明显,是宿主来告诉工作流哪些事件在什么时候发生的。事件在工作流中可以存在一段很长的路径,这一点不同于winform和web程序中的事件(直接从响应者到发起者),工作流实例存在于内存当中,我们得按照一定的规则来唤起工作流和运行,并且这只是一部分,因为工作流可能要等待很长一段时间事件才能到达,很可能工作流这时已被持久化到数据库中去了,工作流不可能在内存中等n个小时甚至更长的时候来等待事件的到达。

 这里所说的规则就是:首先你得定义好事件和相关的参数类型。 

[ExternalDataExchange]

public interface IPaymentProcessingService

{

event EventHandler PaymentProcessed;

}

[Serializable]

public class PaymentProcessedEventArgs : ExternalDataEventArgs

{

public PaymentProcessedEventArgs(Guid instanceId, double amount)

: base(instanceId)

{

_amount = amount;

}

private double _amount;

public double Amount

{         get { return _amount; }

set { _amount = value; }

}

}

 

这里有三点要注意:

(a)我们必须打上ExternalDataExchange标签,在这里,我们不能不提一上数据交换服务:

  什么叫数据交换服务[DataExchangeService]工作流通过专门为此目的建立的服务与外部世界通信。该服务会引发工作流内的事件驱动活动将挂钩到的事件。同样,该服务公开了供该工作流调用的公共方法并向主机发送数据。方法和事件在接口中定义。该接口也称为数据交换服务。每当工作流与外部组件交互(进行输入和输出)时,您都需要该服务

  数据交换服务是常规的 .NET 类库,它最起码包含一个接口定义以及一个实现该接口的类。该

接口是为您希望表示的任务定制的。

  在本例中,[ExternalDataExchange] 属性将 IPaymentProcessingService标记为数据交换服务接口,以便工作流运行库知道它将用来与工作流实例交换数据。在此情况下,宿主将向一串 EventDriven 活动引发事件,从而向工作流实例发送数据

(b)事件中参数类型必须继承自ExternalDataEventArgs类

 ©参数类型必须打上Serializable标签,表示能被序列化。如果没打上此标签,你会发现一些莫明其妙的错误,如:“Event PaymentProcessed on interface type IPaymentProcessingService for instance ID [GUID] cannot be delivered”,这个异常就是因为没有序列化参数的原因。

当我们在Wf中注册这个服务(IPaymentProcessingService)时,运行库将根据ExternalDataExchange标签来找到相应服务接口,当然没找到的时候就会抛出“Service does not implement an interface with the ExternalDataExchange attribute”异常,当运行库找到这个属性标签时,它就会为这些事件生成监听代理类。这些代理类能捕获事件并将他们发送到相应的工作流实列中,当然如果这个工作流长时间休眠在数据库中,他也将被唤醒。

注意到ExternalDataEventArgs类中需要一个guid类型的参数,这个参数就是我们想让事件注册到的工作流实例的标识,activites会验证这些参数是否设置正确。

当我们把

HandleExternalEvent.png

handleExternalEvent  activity拖入到设计器中,我们必须指定这个activity监听的接口和事件,如果我们没有正确按照上面的要求定义好DataExchangeService,那么当你指定的时候会抛出“

The event PaymentProcessed has to be of type EventHandler where T derives from ExternalDataEventArgs”这样的异常,一旦抛出了,你就得好好检查你的DataExchangeService申明是否注意到了我上面所说的那些东西。

对于实现IPaymentProcessingService的类可以如下:

class PaymentProcessingService : IPaymentProcessingService

{

public void ProcessPayment(Guid id, double amount)

{

// ... do some work work work

// ... then raise an event to let everyone know

PaymentProcessedEventArgs args;

args = new PaymentProcessedEventArgs(id, amount);

 

EventHandler evh;

evh = PaymentProcessed;

if (evh != null)

evh(this, args); // boom!

}

public event EventHandler

PaymentProcessed;

}

 工作流实例实际上不需要触发一些服务(如果需要调用的话,你可以使用CallExternalEvent activity),所以我们把Sender参数设为null.

if (evh != null)

evh(null, args); // boom!

}

 

最后我们必参在工作流运行时上配置好这个服务,ExternalDataExchangeService 管理着宿主中本地的服务,所以我们得加上:

WorkflowRuntime workflowRuntime = new WorkflowRuntime();

 ExternalDataExchangeService dataExchangeService;

dataExchangeService = new ExternalDataExchangeService();

workflowRuntime.AddService(dataExchangeService);

PaymentProcessingService paymentProcessing;

paymentProcessing = new PaymentProcessingService();

dataExchangeService.AddService(paymentProcessing);

 //not workflowRuntime.AddService(paymentProcessing);

 这里要注意的是,我们不是在workflowRuntime中注册ExternalDataExchangeService之类服务的。这是我们容易出错的地方

转载于:https://www.cnblogs.com/GoodQ/archive/2007/03/31/694650.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值