阅读文章

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

[日期:2008-04-23] 来源:  作者: [字体: ]

     我们之前写工作流宿主程序一般都是直接写在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+= new EventHandler<WorkflowEventArgs>
   (runtime_WorkflowAborted);
   runtime.WorkflowCompleted+= new EventHandler<WorkflowCompletedEventArgs>
  (runtime_WorkflowCompleted);
   runtime.WorkflowCreated += new EventHandler<WorkflowEventArgs>
  (runtime_WorkflowCreated);
   runtime.WorkflowIdled += new EventHandler<WorkflowEventArgs>(runtime_WorkflowIdled);
   runtime.WorkflowLoaded+= new EventHandler<WorkflowEventArgs>
  (runtime_WorkflowLoaded);
   runtime.WorkflowPersisted += new EventHandler<WorkflowEventArgs>
  (runtime_WorkflowPersisted);
   runtime.WorkflowResumed += new EventHandler<WorkflowEventArgs>
  (runtime_WorkflowResumed);
   runtime.WorkflowStarted+= new EventHandler<WorkflowEventArgs>
  (runtime_WorkflowStarted);
   runtime.WorkflowSuspended+= new EventHandler<WorkflowSuspendedEventArgs>
  (runtime_WorkflowSuspended);
   runtime.WorkflowTerminated+= new EventHandler<WorkflowTerminatedEventArgs>
  (runtime_WorkflowTerminated);
   runtime.WorkflowUnloaded += new EventHandler<WorkflowEventArgs>
  (runtime_WorkflowUnloaded);
   }
  
   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();下面运行结果,从该结果可以清晰的看出工作流的执行过程:
  
    


阅读:
录入:blue1000

评论 】 【 推荐 】 【 打印
上一篇:【C#食谱】【杭帮菜】菜单1:写一个TCP服务端 问题:
下一篇:浅谈基于Mozilla ThunderBird的扩展开发
相关文章      
本文评论
发表评论


点评: 字数
姓名:

  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款