坚持学习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
                < string object > ();
        
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( this new  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 < string object > ();
   wfArguments.Add(
" InputString " " one " );
   WorkflowInstanceWrapper instance 
=  manager.StartWorkflow(
           
typeof (SharedWorkflows.Workflow1), wfArguments);
   instance.WorkflowInstance.Terminate(
" Manually terminated " );
   instance.WaitHandle.WaitOne(
10000 false );
   
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
 上一篇: 
下一篇:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值