坚持学习WF(6):开发可复用的宿主程序

简介:

我们之前写工作流宿主程序一般都是直接写在program.cs文件里,这样复用性比较差。我们就简单的写两个类,这两个类主要实现的是对WorkflowInstance和WorkflowRuntime的封装。我们以后的例子都会使用这两个类。

第一个类是WorkflowInstanceWrapper,代码如下:


 
 
[Serializable]
     public  class WorkflowInstanceWrapper
    {
         private WorkflowInstance _workflowInstance;
         private ManualResetEvent _waitHandle =  new ManualResetEvent( false);
         private Dictionary<String, Object> _outputParameters=  new Dictionary
                < stringobject>();
         private Exception _exception;
         private String _reasonSuspended = String.Empty;

         public WorkflowInstanceWrapper(WorkflowInstance instance)
        {
            _workflowInstance = instance;
        }        
         public Guid Id
        {
             get
            {
                 if (_workflowInstance !=  null)
                    return _workflowInstance.InstanceId;
                 else
                    return Guid.Empty;
            }
        }        
         public Dictionary<String, Object> OutputParameters
        {
             get {  return _outputParameters; }
             set { _outputParameters = value; }
        }        
         public ManualResetEvent WaitHandle
        {
             get {  return _waitHandle; }
             set { _waitHandle = value; }
        }        
         public Exception Exception
        {
             get {  return _exception; }
             set { _exception = value; }
        }        
         public String ReasonSuspended
        {
             get {  return _reasonSuspended; }
             set { _reasonSuspended = value; }
        }        
         public WorkflowInstance WorkflowInstance
        {
             get {  return _workflowInstance; }
        }        
         public  void StopWaiting()
        {
            _waitHandle.Set();
        }
    }

1._exception,_reasonSuspended:表示当工作流非正常终止或挂起时的相关信息。
2. OutputParameters:用来接收工作流的输出参数,工作流运行时引擎将引发 WorkflowCompleted事件。
工作流运行时引擎将在WorkflowCompletedEventArgs 中传入工作流的所有输出参数。 这些参数包括工作
流的 out 和 ref 参数。
 

第二类是WorkflowManager代码如下:  

  public  class WorkflowRuntimeManager : IDisposable
    {
         private WorkflowRuntime _workflowRuntime;
         private Dictionary<Guid, WorkflowInstanceWrapper> _workflows
                               =  new Dictionary<Guid, WorkflowInstanceWrapper>();
      
         public WorkflowRuntimeManager(WorkflowRuntime instance)
        {
            _workflowRuntime = instance;
             if (instance ==  null)
            {
                 throw  new NullReferenceException(
                     " A non-null WorkflowRuntime instance is required ");
            }            
            SubscribeToEvents(instance);
        }

      
         public WorkflowInstanceWrapper StartWorkflow(Type workflowType,
            Dictionary<String, Object> parameters)
        {
            WorkflowInstance instance = _workflowRuntime.CreateWorkflow(
                workflowType, parameters);
            WorkflowInstanceWrapper wrapper
                = AddWorkflowInstance(instance);
            instance.Start();
             return wrapper;
        }
        
         public WorkflowInstanceWrapper StartWorkflow(String markupFileName,
            String rulesMarkupFileName,
            Dictionary<String, Object> parameters)
        {
            WorkflowInstance instance =  null;
            WorkflowInstanceWrapper wrapper =  null;
            XmlReader wfReader =  null;
            XmlReader rulesReader =  null;
             try
            {
                wfReader = XmlReader.Create(markupFileName);
                 if (!String.IsNullOrEmpty(rulesMarkupFileName))
                {
                    rulesReader = XmlReader.Create(rulesMarkupFileName);
                    instance = _workflowRuntime.CreateWorkflow( wfReader, rulesReader, parameters);
                }
                 else
                {
                    instance = _workflowRuntime.CreateWorkflow(wfReader,  null, parameters);
                }
                wrapper = AddWorkflowInstance(instance);
                instance.Start();
            }
             finally
            {
                 if (wfReader !=  null)
                {
                    wfReader.Close();
                }
                 if (rulesReader !=  null)
                {
                    rulesReader.Close();
                }
            }
             return wrapper;
        }

        public WorkflowRuntime WorkflowRuntime
        {
             get {  return _workflowRuntime; }
        }        
         public Dictionary<Guid, WorkflowInstanceWrapper> Workflows
        {
             get {  return _workflows; }
        }        
         public  event EventHandler<WorkflowLogEventArgs> MessageEvent;    

       
         public  void ClearWorkflow(Guid workflowId)
        {
             if (_workflows.ContainsKey(workflowId))
            {
                _workflows.Remove(workflowId);
            }
        }
      
         public  void ClearAllWorkflows()
        {
            _workflows.Clear();
        }
       
         private WorkflowInstanceWrapper AddWorkflowInstance(
            WorkflowInstance instance)
        {
            WorkflowInstanceWrapper wrapper =  null;
             if (!_workflows.ContainsKey(instance.InstanceId))
            {
                wrapper =  new WorkflowInstanceWrapper(instance);
                _workflows.Add(wrapper.Id, wrapper);
            }
             return wrapper;
        }
     
         public WorkflowInstanceWrapper FindWorkflowInstance(Guid workflowId)
        {
            WorkflowInstanceWrapper result =  null;
             if (_workflows.ContainsKey(workflowId))
            {
                result = _workflows[workflowId];
            }
             return result;
        }
       
         public  void WaitAll(Int32 msecondsTimeout)
        {
             if (_workflows.Count >  0)
            {
                WaitHandle[] handles =  new WaitHandle[_workflows.Count];
                Int32 index =  0;
                 foreach (WorkflowInstanceWrapper wrapper
                     in _workflows.Values)
                {
                    handles[index] = wrapper.WaitHandle;
                    index++;
                }
                WaitHandle.WaitAll(handles, msecondsTimeout,  false);
            }
        }
     
         public  void Dispose()
        {
             if (_workflowRuntime !=  null)
            {
                _workflowRuntime.StopRuntime();
                _workflowRuntime.Dispose();
            }
            ClearAllWorkflows();
        }
      
         private  void SubscribeToEvents(WorkflowRuntime runtime)
        {
            runtime.Started +=  new EventHandler<WorkflowRuntimeEventArgs>( runtime_Started);
            runtime.Stopped +=  new EventHandler<WorkflowRuntimeEventArgs>(runtime_Stopped);
            runtime.WorkflowAborted+= ......
            runtime.WorkflowCompleted+= ......
            runtime.WorkflowCreated += ......   
            ............
        }

         void runtime_Started( object sender, WorkflowRuntimeEventArgs e)
        {
            LogStatus(Guid.Empty,  " Started ");
        }
         void runtime_Stopped( object sender, WorkflowRuntimeEventArgs e)
        {
            LogStatus(Guid.Empty,  " Stopped ");
        }
         void runtime_WorkflowCreated( object sender, WorkflowEventArgs e)
        {
            LogStatus(e.WorkflowInstance.InstanceId,  " WorkflowCreated ");
        }
         void runtime_WorkflowStarted( object sender, WorkflowEventArgs e)
        {
            LogStatus(e.WorkflowInstance.InstanceId,  " WorkflowStarted ");
        }
         void runtime_WorkflowIdled( object sender, WorkflowEventArgs e)
        {
            LogStatus(e.WorkflowInstance.InstanceId,  " WorkflowIdled ");
        }

         void runtime_WorkflowCompleted( object sender, WorkflowCompletedEventArgs e)
        {
            LogStatus(e.WorkflowInstance.InstanceId,  " WorkflowCompleted ");
            WorkflowInstanceWrapper wrapper
                = FindWorkflowInstance(e.WorkflowInstance.InstanceId);
             if (wrapper !=  null)
            {
                wrapper.OutputParameters = e.OutputParameters;
                wrapper.StopWaiting();
            }
        }

         void runtime_WorkflowTerminated( object sender,
            WorkflowTerminatedEventArgs e)
        {
            LogStatus(e.WorkflowInstance.InstanceId,  " WorkflowTerminated ");
            WorkflowInstanceWrapper wrapper = FindWorkflowInstance(e.WorkflowInstance.InstanceId);
             if (wrapper !=  null)
            {
                wrapper.Exception = e.Exception;
                wrapper.StopWaiting();
            }
        }

         void runtime_WorkflowSuspended( object sender, WorkflowSuspendedEventArgs e)
        {
            LogStatus(e.WorkflowInstance.InstanceId,  " WorkflowSuspended ");
            WorkflowInstanceWrapper wrapper = FindWorkflowInstance(e.WorkflowInstance.InstanceId);
             if (wrapper !=  null)
            {
                wrapper.ReasonSuspended = e.Error;
            }
        }

         void runtime_WorkflowResumed( object sender, WorkflowEventArgs e)
        {
            LogStatus(e.WorkflowInstance.InstanceId,  " WorkflowResumed ");
        }
         void runtime_WorkflowPersisted( object sender, WorkflowEventArgs e)
        {
            LogStatus(e.WorkflowInstance.InstanceId,  " WorkflowPersisted ");
        }
         void runtime_WorkflowLoaded( object sender, WorkflowEventArgs e)
        {
            LogStatus(e.WorkflowInstance.InstanceId,  " WorkflowLoaded ");
        }
         void runtime_WorkflowAborted( object sender, WorkflowEventArgs e)
        {
            LogStatus(e.WorkflowInstance.InstanceId,  " WorkflowAborted ");
            WorkflowInstanceWrapper wrapper
                = FindWorkflowInstance(e.WorkflowInstance.InstanceId);
             if (wrapper !=  null)
            {
                wrapper.StopWaiting();
            }
        }

         void runtime_WorkflowUnloaded( object sender, WorkflowEventArgs e)
        {
            LogStatus(e.WorkflowInstance.InstanceId,  " WorkflowUnloaded ");
        }

         private  void LogStatus(Guid instanceId, String msg)
        {
             if (MessageEvent !=  null)
            {
                String formattedMsg;
                 if (instanceId == Guid.Empty)
                {
                    formattedMsg = String.Format( " Runtime - {0} ", msg);
                }
                 else
                {
                    formattedMsg = String.Format( " {0} - {1} ", instanceId, msg);
                }
                 // raise the event
                MessageEvent( thisnew WorkflowLogEventArgs(formattedMsg));
            }
        }

    }   
     public  class WorkflowLogEventArgs : EventArgs
    {
         private String _msg = String.Empty;
         public WorkflowLogEventArgs(String msg)
        {
            _msg = msg;
        }

         public String Message
        {
             get {  return _msg; }
        }

1._workflows:一个key为Guid,value为WorkflowInstanceWrapper的字典。
2.SubscribeToEvent():给workflowRuntime订阅事件.
3.StartWorkflow():实现创建,开始工作流.
4.MessageEvent:对Message进行格式化。
5.WaitAll()用来挂起当前的线程直到所有的workflows完成,每个WorkflowInstanceWrapper有一个WaitHandle属性以便宿主程序能灵活控制。 

下面是测试代码:

 
 
using (WorkflowRuntimeManager manager
        =  new WorkflowRuntimeManager( new WorkflowRuntime( " WorkflowRuntime ")))
{
   manager.MessageEvent +=  delegate(Object sender, WorkflowLogEventArgs e)
   {
      Console.WriteLine(e.Message);
   };
   manager.WorkflowRuntime.StartRuntime();
   Dictionary<String, Object> wfArguments=  new Dictionary< stringobject>();
   wfArguments.Add( " InputString "" one ");
   WorkflowInstanceWrapper instance = manager.StartWorkflow(
            typeof(SharedWorkflows.Workflow1), wfArguments);
   instance.WorkflowInstance.Terminate( " Manually terminated ");
   instance.WaitHandle.WaitOne( 10000false);
    foreach (WorkflowInstanceWrapper wrapperin manager.Workflows.Values)
   {
        if (wrapper.OutputParameters.ContainsKey( " Result "))
       {
            Console.WriteLine(wrapper.OutputParameters[ " Result "]);
       }
        if (wrapper.Exception !=  null)
       {
     Console.WriteLine( " {0}-Exception:{1} ",wrapper.Id,wrapper.Exception.Message);
       }
        if (wrapper.ReasonSuspended.Length >  0)
       {
    Console.WriteLine( " {0}-Suspended: {1} ",wrapper.Id, wrapper.ReasonSuspended);
       }
}    manager.ClearAllWorkflows();























下面运行结果,从该结果可以清晰的看出工作流的执行过程:


1
 上一篇:坚持学习WF(5):自定义活动(CustomActivity) 
下一篇:坚持学习WF(7):流程控制(Flow Control)



本文转自生鱼片博客园博客,原文链接:http://www.cnblogs.com/carysun/archive/2008/04/21/1164609.html,如需转载请自行联系原作者

目录
相关文章
|
5天前
|
存储 人工智能 安全
AI 越智能,数据越危险?
阿里云提供AI全栈安全能力,为客户构建全链路数据保护体系,让企业敢用、能用、放心用
|
8天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
7天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
448 93
|
1天前
|
开发者
「玩透ESA」ESA启用和加速-ER在加速场景中的应用
本文介绍三种配置方法:通过“A鉴权”模板创建函数并设置触发器路由;在ESA上配置回源302跟随;以及自定义响应头。每步均配有详细截图指引,帮助开发者快速完成相关功能设置,提升服务安全性与灵活性。
287 2
|
7天前
|
SQL 人工智能 自然语言处理
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
随着生成式AI的普及,Geo优化(Generative Engine Optimization)已成为企业获客的新战场。然而,缺乏标准化流程(Geo优化sop)导致优化效果参差不齐。本文将深入探讨Geo专家于磊老师提出的“人性化Geo”优化体系,并展示Geo优化sop标准化如何帮助企业实现获客效率提升46%的惊人效果,为企业在AI时代构建稳定的流量护城河。
409 156
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
|
7天前
|
数据采集 缓存 数据可视化
Android 无侵入式数据采集:从手动埋点到字节码插桩的演进之路
本文深入探讨Android无侵入式埋点技术,通过AOP与字节码插桩(如ASM)实现数据采集自动化,彻底解耦业务代码与埋点逻辑。涵盖页面浏览、点击事件自动追踪及注解驱动的半自动化方案,提升数据质量与研发效率,助力团队迈向高效、稳定的智能化埋点体系。(238字)
316 158