• 宿主和工作流:两个世界的交互 II(工作流给Host传递数据) Virus


           在上一篇中
    http://www.cnblogs.com/virusswb/archive/2008/11/25/1340631.html
           我们理解了如何在启动的时候从Host传递数据给工作流,如果我们不需要从工作流返回数据的话,前面的工作就足够了。但是很多时候,我们都想要从工作流中返回一些处理的数据。
        微软的工作流框架为我们提供了一个活动CallExternalMethod,来完成这样一件事。
           回想上一章的列子,我们的Host程序从计算机中读取一个文件,读取一定数量的字符,在工作流中显示内容。在程序中我们要传递两个参数(一个是文件的路径,一个是从文件返回的字符数量),在工作流用MessageBox显示内容。现在,我们需要在Host的控制台中显示这些从工作流返回的信息,而不是在工作流的MessageBox中显示。如下图所示
    wf5.JPG
           为了实现从工作流传递数据给Host,微软提供一个专门用于这个功能的活动,叫做CallExternalMethod,这是一个好消息,坏消息是我们必须自定义一个和这个活动交流的服务模式。
          交互服务模式是另外一种服务,你必须创建一个服务的接口,实现这个接口,然后在工作流运行时 Workflow runtime 中注册实现这个接口的实例。你可以实现你想要的交互,事件或者poll (这个单词不知道如何来翻译),但是你必须满足CallExternalMethod的要求。简单来说看你需要实现下面的代码结构。

            创建下面的类和接口:
          1、创建一个被CallExternalMethod活动调用的接口和相应的方法
          2、一个实现上面的接口的类。在类中,我们要实现接口中定义的被CallExternalMethod调用的方法,方法的内容就是你的工作流发送数据到Host。
          3、如果你要用事件来驱动交互,你必须实现一个继承自EventArgs 的类,用来存储你要发送给Host的信息。

          在Host程序中要做下面的事情:
          1、你应该创建一个ExternalDataExchangeService 类的实例,并在工作流运行时中注册它。
          2、你也要在数据服务类(ExternalDataExchangeService) 中的注册你的自定义的交互服务。
          3、如果你使用事件驱动交互,你还要在Host程序中进行事件的处理。
          
          在工作流中:
          1、你必须有一个叫做CallExternalMethod的活动
          2、在CallExternalMethod活动中注册一个接口和调用的方法
    下图是类的结构
    wf6.JPG

    你可以看见CallExternalMethod活动在另外一个线程中调用了的方法,当方法执行的时候,在Host中我们就会看到消息。
           下面开始我们的代码设计,一步一步的使用CallExternalMethod来实现。
    1、创建下面的接口和类
           你可以在单独的类库中创建接口和类,简单起见就在当前项目下面创建。

    namespace CommunicationCallExternalMethod
    {
        
    /// <summary>
        
    /// You MUST to mark the interface with the header ExternalDataExchange
        
    /// to identify the interface as the communication interface.
        
    /// </summary>
        [ExternalDataExchange]
        
    public interface ICommunicationService
        {
             
    /// <summary>
            
    /// This method must be call by the CallExternalMethod Activity
            
    /// to transfer the information to the console host application
            
    /// </summary>
            ///
     <param name="response">Data to send to console</param>
            
    void SendDataToHost(string response);
        }
    }

    从名字上面来看,很容易明白,接口的方法用来给Host发送数据。特性[ExternalDataExchange]说明类型中的方法可以被工作流调用。
    2、实现上面接口的类
    在类中你可以将方法实现为简单的传递数据给Host,Host poll类实例,或者你也可以用事件来异步的获取数据。
        在我们的代码中我们实现了事件,我们将数据通过工作流事件的参数传递。
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace CommunicationCallExternalMethod
    {
        
        
    /// <summary>
        
    /// Implement the interface
        
    /// This implementation is made to comunicate WF -> Host
        
    /// </summary>
        
    public class CommunicationService: ICommunicationService
        {

            
    /// <summary>
            
    /// Event to communicate the host the result.
            
    /// </summary>
            
    public event EventHandler<SendDataToHostEventArgs> SendDataToHostEvent;
            
    /// <summary>
            
    /// Implement the external Method
            
    /// </summary>
            ///
     <param name="response">response to host</param>
            
    public void SendDataToHost(string response)
            {
                SendDataToHostEventArgs e 
    = new SendDataToHostEventArgs();
                e.Response 
    = response;
                EventHandler
    <SendDataToHostEventArgs> sendData = this.SendDataToHostEvent; 
                
    if (sendData != null)
                {
                    sendData(
    this, e);
                }
            }
        }
    }

    从上面我们可以看出来,方法只是简单的将数据传递给事件的参数,并且触发事件。事件参数的定义如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Workflow.Activities;

    namespace CommunicationCallExternalMethod
    {
        
    public class SendDataToHostEventArgs: EventArgs
        {
            
    string _response = string.Empty;
            
    /// <summary>
            
    /// This property is used to pass in the Event the response to host
            
    /// </summary>
            
    public string Response
            {
                
    get
                { 
    return _response; }
                
    set
                { _response 
    = value; }
            }

        }
    }

    在我们的例子中创建了三个类,分别是:
  • SendDataToHostEventArgs.cs
  • CommunicationService.cs
  • ICommunicationService.cs

3、注册我们自定义的交互服务作为工作流的ExternalDataExchangeService外部数据交互服务

注册过程是在工作流运行时中进行,可以参照下面的代码
ExternalDataExchangeService dataservice = new ExternalDataExchangeService();
//Add to workflow runtime
workflowRuntime.AddService(dataservice);
//Declare our CommunicationService instance
CommunicationService cservice 
= new CommunicationService();
//Add to the ExternalDataService
dataservice.AddService(cservice);
//Add a handler to Service Event
cservice.SendDataToHostEvent 
+= new EventHandler<senddatatohosteventargs> (cservice_SendDataToHostEvent);

第一步是注册交互服务,接下来是注册事件的处理程序

4、在工作流设计界面进行设置
就用上一章我们建立的工作流就可以,拖拽一个CallExternalMethod  活动到设计界面上来,设置如下

wf7.JPG
选择InterfaceType 属性为ICommunicationService,在MethodName属性中选择接口的SendDataToHost方法,将方法的参数response,也就是消息的内容绑定到工作流的一个属性上来,可以实现动态绑定更新工作流的属性。

使用CallExternalMethod 活动, 从工作流传递数据给Host的基本步骤如下:
1、创建下面的接口和类
      1)一个被CallExternalMethod 活动调用的接口方法,并且标记接口为[ExternalDataExchange]
      2)一个实现接口的类,类中实现被[CallExternalMethod ]活动调用的方法,
2、在Host程序中做下面的事情
      1)为工作流运行时注册一个ExternalDataExchangeService类 的实例
              
               ExternalDataExchangeService dataservice = new ExternalDataExchangeService();
                //Add to workflow runtime
                workflowRuntime.AddService(dataservice);
      2)为ExternalDataExchangeService类 的实例添加交互的实例
              
               CommunicationService cservice = new CommunicationService();
                //Add to the ExternalDataService
                dataservice.AddService(cservice);
                //Add a handler to Service Event
      3)如果你使用事件驱动交互,在你的Host程序中要定义事件处理
 cservice.SendDataToHostEvent += new EventHandler<SendDataToHostEventArgs>(cservice_SendDataToHostEvent);
  3、在工作流中
      1)拖拽一个CallExternalMethod 活动到设计器中,
      2)设置CallExternalMethod 活动的接口和方法,绑定参数

      现在为止,你有了一个从Host到工作流的单向交互,但是你还是有局限,直到现在你只是知道如何给工作流传递初始化数据,但是你还不知道在如何随时给工作流传递参数?在下一章我们将会讲到这些。

【Blog】http://virusswb.cnblogs.com/

【MSN】jorden008@hotmail.com

【说明】转载请标明出处,谢谢

反馈文章质量,你可以通过快速通道评论:

  • 相关阅读:
    7.10.8107.79 小心80180048
    Sliverlight MD5
    WP 数据绑定Visibility
    WP7 剪贴板 Clipboard
    [10年之后我是谁]读书笔记
    linux面试题
    [你的灯亮着吗]读书笔记
    Linux命令行简明教程
    <Ruby入门教程>读书笔记
    [职场谎言系列]读书笔记
  • 原文地址:https://www.cnblogs.com/virusswb/p/1340697.html
  • Copyright © 2020-2023  润新知