我们之前写工作流宿主程序一般都是直接写在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();
下面运行结果,从该结果可以清晰的看出工作流的执行过程:
上一篇:坚持学习WF(5):自定义活动(CustomActivity)
下一篇:坚持学习WF(7):流程控制(Flow Control)