我们之前写工作流宿主程序一般都是直接写在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; }
}
{
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();
下面运行结果,从该结果可以清晰的看出工作流的执行过程:
上一篇:坚持学习WF(5):自定义活动(CustomActivity)
下一篇:坚持学习WF(7):流程控制(Flow Control)
发表评论
-
平淡的2007
2007-12-24 08:04 784早上起来,送女朋友去公交车站,然后回来赶紧打开电脑,先 ... -
DreamSpark发布,高校学生免费使用Visual Studio 2008 Professional Edition 等微软软件
2008-02-20 13:23 1380今天上网无意中搜索到学生可以免费使用VS2008专业版,后来又 ... -
坚持学习WF(1):从HelloWorld开始
2008-04-04 16:30 849[置顶]坚持学习WF文章索 ... -
坚持学习WF(2):WF创作模式和设计时工具
2008-04-05 17:19 599[置顶]坚持学习WF文章索 ... -
坚持学习WF(3):WF框架概览
2008-04-08 07:27 736[置顶]坚持学习WF文章索 ... -
坚持学习WF(4):活动(Activity)和依赖属性(DependencyProperty)
2008-04-12 00:01 1101[置顶]坚持学习WF文章索引 活动(Activity) 活动 ... -
坚持学习WF(5):自定义活动(CustomActivity)
2008-04-13 15:25 881当WF提供的标准活动不能满足我们的需求的时候,我们就需要定义自 ... -
MOSS点滴(1):如何开发和部署feature
2008-04-16 21:35 806Features 是MOSS 2007以开箱即用的一套新功能, ... -
MOSS点滴(2):自定义Application Page
2008-04-19 20:07 809在MOSS中后台管理的页面都是Application Pag ... -
MOSS点滴(3):说说MOSS中的母版页
2008-04-25 21:15 1135MOSS中有两种页面:Site P ... -
MOSS点滴(4):实现Form认证
2008-04-29 21:12 666本文主要参考了网上的一些文章,但有些文章有些地方说的不是很明确 ... -
坚持学习WF(7):流程控制(Flow Control)
2008-04-30 18:10 772本文主要说说WF中和流 ... -
坚持学习WF(8):本地服务之调用外部方法
2008-05-09 08:17 718WF提供了一组核心服务 ... -
MOSS中的WebPart开发
2008-05-10 13:53 1024由于在asp.net1.1的时候asp.net中还没有webp ... -
坚持学习WF(9):本地服务之事件处理
2008-05-28 07:49 763[置顶]坚持学习WF文章索引 一:先来介绍两个活动 Even ... -
坚持学习WF(10):在工作流中使用关联
2008-06-01 13:03 658[置顶]坚持学习WF文章索 ... -
坚持学习WF(11):工作流通信与队列
2008-06-07 15:45 692[置顶]坚持学习WF文章索引 WF 提供的通信模型是构建于 ... -
MOSS中创建自定义内容类型
2008-06-12 20:23 1068一:简要介绍 某类内容 ... -
.NET中IDisposable接口的基本使用
2008-06-15 12:01 908首先来看MSDN中关于这个接口的说明: [ComVisible ... -
坚持学习WF(12):使用EventHandlingScopeActivity活动
2008-06-18 22:46 639[置顶]坚持学习WF文章索引 EventHandlingSco ...
相关推荐
坚持学习WF(6):开发可复用的宿主程序 主要实现两个类来对WorkflowInstance和WorkflowRuntime进行简单的封装。 坚持学习WF(7):流程控制(Flow Control) 主要说了WF中和流程相关的活动,主要包括以下这些活动:...
坚持学习WF(6):开发可复用的宿主程序 主要实现两个类来对WorkflowInstance和WorkflowRuntime进行简单的封装。 坚持学习WF(7):流程控制(Flow Control) 主要说了WF中和流程相关的活动,主要包括以下这些活动:...
我们之前写工作流宿主程序一般都是直接写在program.cs文件里,这样复用性比较差。我们就简单的写两个类,这两个类主要实现的是对WorkflowInstance和WorkflowRuntime的封装。我们以后的例子都会使用这两个类。
坚持学习WF(6):开发可复用的宿主程序 主要实现两个类来对WorkflowInstance和WorkflowRuntime进行简单的封装。 坚持学习WF(7):流程控制(Flow Control) 主要说了WF中和流程相关的活动,主要包括以下这些活动:...
坚持学习WF(1):从HelloWorld开始 源码
坚持学习WF(5):自定义活动(CustomActivity) 源码
WF4.0 实战(二十一):Windows Server AppFabric中宿主WF4.0应用程序
Visual Studio 2008开发新特性系列课程(7):使用WCF,WF,Cardspace创建互联的应用程序
该文档描述了投币器微信打印机WF-700B投币器脉冲输入转串口数据的适配器测试及程序开发说明。
wf开发文档
WF高级程序设计.pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
图灵WF高级程序设计 纯净版 有的版本有很多广告链接,整理了一下,重新发布 图灵WF高级程序设计 纯净版 有的版本有很多广告链接,整理了一下,重新发布 图灵WF高级程序设计 纯净版 有的版本有很多广告链接,整理了...
Beginning WF: Windows Workflow in .NET 4.0 By Mark Collins Publisher: Apress 2010 | 500 Pages | ISBN: 1430224851 | PDF | 4 MB Windows Workflow Foundation is a ground-breaking addition to the core ...
WF的全称是Windows Workflow Foundation,是...WF不是一个独立的工作流应用程序,它提供了一些类库用于辅助工作流应用程序的开发,并提供了实现工作流应用程序时所需要实现的一些机制,比如持久化、补偿、跟踪机制等。
WF5803/WF100D驱动代码及资料,包含IIC、三线SPI、四线SPI驱动代码
Windows Workflow Foundation (WF) is a revolutionary part of the .NET 4 Framework that allows you to orchestrate human and system interactions as a series of workflows that can be easily mapped, ...
LG156WF6+SPB1.zip 为了保证颜色的准确,设计师必须先从一个不起眼,但起到决定性作用的数据文件--ICC文件开始,着手打造自己的准确色彩。
vs2008视频教程7:使用WCF,WF,Cardspace创建互联的应用程序
爱普生wf7111w7620wf7621清零强力清洗软件,支持爱普生wf7111wf7621清零强力清洗软件, 实测wf7620也可以用,估计wf7610也能用