代码改变世界

宿主和工作流:两个世界的交互 I (Host给工作流传递初始化数据)

2008-11-25 14:10  Virus-BeautyCode  阅读(569)  评论(1编辑  收藏  举报

      在CodeProject中有一篇介绍宿主程序如何和工作流进行交互,使用wf提供的两个活动就可以实现,分别是callExternalMethodActivity1和handleExternalEventActivity1活动,在后面会详细介绍。
      宿主和工作流的交互是非常常用的,因为他们是运行在不同的线程中的。

      首先介绍如何从宿主传递数据给工作流,一般都是初始化的数据,例如,工作流什么时候启动等,除了这些我们就不需要其他的交互了。
可以想象一种情况,我们想要从计算机读取一个文件,读取一定数量的字符。
我们可以想象一个这样的程序,你能传递两个参数(文件的路径和字符的数量),在工作流的内部使用MessageBox显示文件的信息。请看下图
   wf4.JPG
      User输入参数,运行控制台程序,控制台程序运行在一个线程中,相当于前面提到的Host,工作流运行在另外一个线程中,在Host要初始化工作流并且传递刚才输入的参数,在工作流中根据参数打开文件,读取一定数量的字符内容,用弹出窗体来显示内容,User看到内容。
      在以往的学习中我们已经知道,给工作流传递参数,我们要使用Dictionary<string, object> ,
工作流类的完整代码如下

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Linq;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;

namespace com.kimbanx.sharepoint.wf
{
    
public partial class Workflow1 : SequentialWorkflowActivity
    {
        
string _filepath = string.Empty;
        
int _quantity = 0;
        
//Variable to hold the result
        
string _result = string.Empty;
        
/// <summary>
        
/// The Property name must be the same as the object in the 
        
/// input parameter dictionary
        
/// </summary>
        
public int Quantity
        {
            
get { return _quantity; }
            
set { _quantity = value; }
        }
        
/// <summary>
        
/// The Property name must be the same as the object in the 
        
/// input parameter dictionary 
        
/// </summary>
        
public string FilePath
        {
            
get { return _filepath; }
            
set { _filepath = value; }
        }
    }
}


Host(就是我们这里的控制台程序)的代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;

namespace CallExternalMethodDemo
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
            {
                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();
                };

                Dictionary
<stringobject> argumentDictionary = new Dictionary<stringobject>();

                
//Pass the first parameter: the file path. You must use the same name that was defined as variable in the workflow.

                argumentDictionary.Add("
FilePath", _filepath);

                argumentDictionary.Add(
"Quantity", _readQuantity);

                WorkflowInstance instance 
= workflowRuntime.CreateWorkflow(typeof(CallExternalMethodDemo.Workflow1),argumentDictionary);
                instance.Start();

                waitHandle.WaitOne();
            }
        }
    }
}

从Host给工作流传递数据的三个基本步骤是:
1、在工作流中创建必要属性,用来接收传递过来的数据
2、在Host程序中创建  Dictionary<stringobject>的实例,用来存储初始化参数数据
3、使用CreateWorkflow的重载方法,将 Dictionary<stringobject>的实例作为参数传递给工作流   
      上面的例子中我们只需要给工作流传递数据,但是什么时候工作流需要传递数据给我们的Host呢?在接下来的文章中我们将会讲到。

谢谢!