1.workflowruntime启动了持久化和监听服务
2.workfllowruntime创建多个实例,并启动,一些会长时间延时,一些会中途暂停,会不同的执行状态(业务状态)
3.另有一winform控制台,有个表格,刷新显示每个实例的信息,包括业务状态--比如创建,运行,挂起等
4.通过workflowruntime.GetLoadedWorkflows()方法取得所有实例,但却没有办法得到正确的业务状态
当然,当将实例unload,再load后(实例回写到数据库),通过SqlTrackingQuery查询得到SqlTrackingWorkflowInstance.Status是可以.可是实际上,不可能一刷新实例表格就要将实例unload.所以,在想有没有办法在workflowruntime平台上,获取实例的业务状态.
决定自己写个类,解决这个问题,思路如下:
1.在宿主中构建Dictionary<Guid, TrackingStatus>,用于维护instance状态
2.预订workflowruntime与instance相关的事件
3.在事件处理方法中更新instance对应的trackingstatus
4.定义event WorkflowStatusChangeEventHandler WorkflowStatusChanged事件,以便状态变化时处理
两个类:
1
using System;2
using System.Collections.Generic;3
using System.Text;4

5
using System.Workflow;6
using System.Workflow.Runtime;7
using System.Workflow.Runtime.Hosting;8
using System.Workflow.Runtime.Tracking;9
using System.Workflow.Activities;10
using System.Workflow.ComponentModel;11

12
namespace WFDebugger13


{14
public class TrackingStatus15

{16
private WorkflowInstance instance;17
private WorkflowStatus status;18
private DateTime lasteventtime;19

20
public TrackingStatus(WorkflowInstance instance, WorkflowStatus status, System.DateTime eventtime)21

{22
if (instance == null || eventtime == null)23

{24
throw(new ArgumentNullException("instance|status|eventtime"));25
}26
this.instance = instance;27
this.status = status;28
this.lasteventtime = eventtime;29
}30

31
public TrackingStatus(WorkflowInstance instance, WorkflowStatus status)32

{33
if (instance == null)34

{35
throw (new ArgumentNullException("instance|status|eventtime"));36
}37
this.instance = instance;38
this.status = status;39
this.lasteventtime = DateTime.Now;40
}41
42
public WorkflowInstance Instance43

{44
get45

{46
return instance;47
}48
}49

50
public WorkflowStatus Status51

{52
get53

{54
return status;55
}56
}57

58
public DateTime LastEventTime59

{60
get61

{62
return lasteventtime;63
}64
}65

66
public void ChangeStatus(WorkflowStatus status, DateTime eventtime)67

{68
if (!TryChangeStatus(status, eventtime,new TimeSpan(0,0,10)))69

{70
throw(new Exception("can't lock variable"));71
}72
}73

74
public void ChangeStatus(WorkflowStatus status)75

{76
ChangeStatus(status, DateTime.Now);77
}78

79
public bool TryChangeStatus(WorkflowStatus status, DateTime eventtime,TimeSpan timeout)80

{81
if (System.Threading.Monitor.TryEnter(this.status, timeout))82

{83
this.status = status;84
lasteventtime = eventtime;85
return true;86
}87
else88

{89
return false;90
}91
}92
public bool TryChangeStatus(WorkflowStatus status, TimeSpan timeout)93

{94
return TryChangeStatus(status,DateTime.Now, timeout);95
}96
}97
}98

99

1
using System;2
using System.Collections;3
using System.Collections.Generic;4
using System.Data;5

6
using System.Workflow;7
using System.Workflow.Runtime;8
using System.Workflow.Runtime.Hosting;9
using System.Workflow.Runtime.Tracking;10
using System.Workflow.Activities;11
using System.Workflow.ComponentModel;12
using System.Collections.ObjectModel;13

14

15

16
namespace WFDebugger17


{18
class TrackingWorkflowEvent:IDisposable 19

{20

21

事件#region 事件22
public delegate void WorkflowStatusChangeEventHandler(object sender, WorkflowStatusChangeEventArgs e);23
public event WorkflowStatusChangeEventHandler WorkflowStatusChanged;24
void RaiseWorkflowStatusChangeEvent(WorkflowRuntime runtime,WorkflowStatusChangeEventArgs e)25

{26
if (WorkflowStatusChanged != null)27

{28
WorkflowStatusChanged.Invoke(runtime, e);29
}30
}31
#endregion32

33

私有变量#region 私有变量34
private WorkflowRuntime workflowruntime;35
private SqlTrackingService trackingservice;36
private SqlWorkflowPersistenceService persistenceService;37
private bool initialized = false;38
private bool tacked = false;39

40
private Dictionary<Guid, TrackingStatus> dic = new Dictionary<Guid, TrackingStatus>();41

42
#endregion43

44
public TrackingWorkflowEvent(WorkflowRuntime workflowruntime)45

{46
if (workflowruntime != null)47

{48
this.workflowruntime = workflowruntime;49
ReadOnlyCollection<SqlTrackingService> tcol = workflowruntime.GetAllServices<SqlTrackingService>();50
if (tcol != null && tcol.Count > 0)51

{52
trackingservice = tcol[0];53
}54
else55

{56
throw (new Exception("Workflowruntime havn't TrackingService."));57
}58

59
ReadOnlyCollection<SqlWorkflowPersistenceService> pcol = workflowruntime.GetAllServices<SqlWorkflowPersistenceService>();60
if (pcol != null && pcol.Count > 0)61

{62
persistenceService = pcol[0];63
}64
else65

{66
throw (new Exception("Workflowruntime havn't WorkflowPersistenceService."));67
}68

69
//runtime event70
workflowruntimeStarted = new EventHandler<WorkflowRuntimeEventArgs>(workflowRuntime_Started);71
workflowruntimeServicesExceptionNotHandled = new EventHandler<ServicesExceptionNotHandledEventArgs>(workflowRuntime_ServicesExceptionNotHandled);72
workflowruntimeStopped = new EventHandler<WorkflowRuntimeEventArgs>(workflowRuntime_Stopped);73

74
//instance event75
workflowruntimeWorkflowCompleted = new EventHandler<WorkflowCompletedEventArgs>(workflowRuntime_WorkflowCompleted);76
workflowruntimeWorkflowTerminated = new EventHandler<WorkflowTerminatedEventArgs>(workflowRuntime_WorkflowTerminated);77
workflowruntimeWorkflowSuspended = new EventHandler<WorkflowSuspendedEventArgs>(workflowRuntime_WorkflowSuspended);78
workflowruntimeWorkflowAborted = new EventHandler<WorkflowEventArgs>(workflowRuntime_WorkflowAborted);79
workflowruntimeWorkflowResumed = new EventHandler<WorkflowEventArgs>(workflowRuntime_WorkflowResumed);80
workflowruntimeWorkflowLoaded = new EventHandler<WorkflowEventArgs>(workflowRuntime_WorkflowLoaded);81
workflowruntimeWorkflowIdled = new EventHandler<WorkflowEventArgs>(workflowRuntime_WorkflowIdled);82
workflowruntimeWorkflowPersisted = new EventHandler<WorkflowEventArgs>(workflowRuntime_WorkflowPersisted);83
workflowruntimeWorkflowUnloaded = new EventHandler<WorkflowEventArgs>(workflowRuntime_WorkflowUnloaded);84
workflowruntimeWorkflowCreated = new EventHandler<WorkflowEventArgs>(workflowRuntime_WorkflowCreated);85
workflowruntimeWorkflowStarted = new EventHandler<WorkflowEventArgs>(workflowRuntime_WorkflowStarted);86

87
initialized = true;88
}89
else90

{91
throw (new ArgumentNullException("workflowruntime"));92
}93
}94

95

私有方法#region 私有方法96
private bool AddInstance(WorkflowInstance instance)97

{98
if (instance == null)99

{100
throw(new ArgumentNullException("instance"));101
}102
if (instance.WorkflowRuntime != workflowruntime)103

{104
throw (new Exception("different workflowruntime"));105
}106
SqlTrackingQuery sq = new SqlTrackingQuery(trackingservice.ConnectionString);107
SqlTrackingWorkflowInstance sqi ;108
if (sq.TryGetWorkflow(instance.InstanceId, out sqi))109

{110
dic.Add(instance.InstanceId, new TrackingStatus(instance, sqi.Status));111
RaiseWorkflowStatusChangeEvent(workflowruntime, new WorkflowStatusChangeEventArgs(instance,sqi.Status));112
return true;113
}114
else115
return false;116
}117
private bool AddInstance(WorkflowInstance instance,WorkflowStatus status)118

{119
if (instance == null)120

{121
throw (new ArgumentNullException("instance"));122
}123
if (instance.WorkflowRuntime != workflowruntime)124

{125
throw (new Exception("different workflowruntime"));126
}127
dic.Add(instance.InstanceId, new TrackingStatus(instance, status));128
RaiseWorkflowStatusChangeEvent(workflowruntime, new WorkflowStatusChangeEventArgs(instance, status));129
return true;130
}131

132
private void RemoveInstance(WorkflowInstance instance)133

{134
if (instance == null)135

{136
throw (new ArgumentNullException("instance"));137
}138
if (instance.WorkflowRuntime != workflowruntime)139

{140
throw (new Exception("different workflowruntime"));141
}142
RemoveInstance(instance.InstanceId);143
}144
private void RemoveInstance(Guid instanceid)145

{146
//if (instanceid == null)147
//{148
// throw (new ArgumentNullException("instanceid"));149
//}150
if (dic.ContainsKey(instanceid))151

{152
dic.Remove(instanceid);153
}154
else155

{156
throw (new Exception("no found appointed instance"));157
}158

159

160
}161
private bool ChangeStatus(WorkflowInstance instance, WorkflowStatus status)162

{163
if (instance == null)164

{165
throw (new ArgumentNullException("instance"));166
}167
//if (status == null)168
//{169
// throw (new ArgumentNullException("status"));170
//}171
if (dic.ContainsKey(instance.InstanceId))172

{173
TrackingStatus ts = dic[instance.InstanceId];174
bool r = ts.TryChangeStatus(status,new TimeSpan(0,0,10));175
RaiseWorkflowStatusChangeEvent(workflowruntime, new WorkflowStatusChangeEventArgs(instance, status));176
return r;177
}178
else179

{180
return false;181
//return AddInstance(instance, status);182
}183

184

185
}186
#endregion187

188

公开属性#region 公开属性189

/**//// <summary>190
/// 工作流环境191
/// </summary>192
public WorkflowRuntime WorkflowRuntime193

{194
get195

{196
return workflowruntime;197
}198
}199

200

/**//// <summary>201
/// 实例数量202
/// </summary>203
public int Count204

{205
get206

{207
return dic.Count;208
}209
}210

211

/**//// <summary>212
/// 是否在跟踪213
/// </summary>214
public bool IsOnTracking215

{216
get217

{218
return tacked;219
}220
}221

/**//// <summary>222
/// 是否初始化223
/// </summary>224
public bool Initialized225

{226
get227

{228
return initialized;229
}230
}231
public WorkflowStatus GetWorkflowStatus(Guid instanceID)232

{233
//if (instanceID == null)234
//{235
// throw(new ArgumentNullException("instanceID"));236
//}237
if (dic.ContainsKey(instanceID))238

{239
return dic[instanceID].Status;240
}241
else242

{243
throw(new Exception("no found appointed instance"));244
//return AddInstance(instance, status);245
}246
}247
public WorkflowStatus GetWorkflowStatus(WorkflowInstance instance)248

{249
if (instance == null)250

{251
throw (new ArgumentNullException("instance"));252
}253
if (instance.WorkflowRuntime != workflowruntime)254

{255
throw (new Exception("different workflowruntime"));256
}257
return GetWorkflowStatus(instance.InstanceId);258
}259

260
#endregion 261

262

Runtime Event#region Runtime Event263
264

事件句柄#region 事件句柄265
//runtime event266
EventHandler<WorkflowRuntimeEventArgs> workflowruntimeStarted;267
EventHandler<ServicesExceptionNotHandledEventArgs> workflowruntimeServicesExceptionNotHandled;268
EventHandler<WorkflowRuntimeEventArgs> workflowruntimeStopped;269

270
//instance event271
EventHandler<WorkflowCompletedEventArgs> workflowruntimeWorkflowCompleted;272
EventHandler<WorkflowTerminatedEventArgs> workflowruntimeWorkflowTerminated;273
EventHandler<WorkflowSuspendedEventArgs> workflowruntimeWorkflowSuspended;274
EventHandler<WorkflowEventArgs> workflowruntimeWorkflowAborted;275
EventHandler<WorkflowEventArgs> workflowruntimeWorkflowResumed;276
EventHandler<WorkflowEventArgs> workflowruntimeWorkflowLoaded;277
EventHandler<WorkflowEventArgs> workflowruntimeWorkflowIdled;278
EventHandler<WorkflowEventArgs> workflowruntimeWorkflowPersisted;279
EventHandler<WorkflowEventArgs> workflowruntimeWorkflowUnloaded;280
EventHandler<WorkflowEventArgs> workflowruntimeWorkflowCreated;281
EventHandler<WorkflowEventArgs> workflowruntimeWorkflowStarted;282

283
public void TackEvent()284

{285
if (initialized && !tacked)286

{287

预定事件#region 预定事件288
//runtime event289
workflowruntime.Started += workflowruntimeStarted;290
workflowruntime.ServicesExceptionNotHandled += workflowruntimeServicesExceptionNotHandled;291
workflowruntime.Stopped += workflowruntimeStopped;292

293
//instance event294
workflowruntime.WorkflowCompleted += workflowruntimeWorkflowCompleted;295
workflowruntime.WorkflowTerminated += workflowruntimeWorkflowTerminated;296
workflowruntime.WorkflowSuspended += workflowruntimeWorkflowSuspended;297
workflowruntime.WorkflowAborted += workflowruntimeWorkflowAborted;298
workflowruntime.WorkflowResumed += workflowruntimeWorkflowResumed;299
workflowruntime.WorkflowLoaded += workflowruntimeWorkflowLoaded;300
workflowruntime.WorkflowIdled += workflowruntimeWorkflowIdled;301
workflowruntime.WorkflowPersisted += workflowruntimeWorkflowPersisted;302
workflowruntime.WorkflowUnloaded += workflowruntimeWorkflowUnloaded;303
workflowruntime.WorkflowCreated += workflowruntimeWorkflowCreated;304
workflowruntime.WorkflowStarted += workflowruntimeWorkflowStarted;305
#endregion306
tacked = true;307
}308
else309

{310
throw( new Exception("TrackingWorkflowEvent didn't initialized or TrackingInstanceEvent tacked event"));311
}312
}313

314
public void UntackEvent()315

{316
if (initialized && tacked)317

{318

卸载事件#region 卸载事件319
//runtime event320
workflowruntime.Started -= workflowruntimeStarted;321
workflowruntime.ServicesExceptionNotHandled -= workflowruntimeServicesExceptionNotHandled;322
workflowruntime.Stopped -= workflowruntimeStopped;323

324
//instance event325
workflowruntime.WorkflowCompleted -= workflowruntimeWorkflowCompleted;326
workflowruntime.WorkflowTerminated -= workflowruntimeWorkflowTerminated;327
workflowruntime.WorkflowSuspended -= workflowruntimeWorkflowSuspended;328
workflowruntime.WorkflowAborted -= workflowruntimeWorkflowAborted;329
workflowruntime.WorkflowResumed -= workflowruntimeWorkflowResumed;330
workflowruntime.WorkflowLoaded -= workflowruntimeWorkflowLoaded;331
workflowruntime.WorkflowIdled -= workflowruntimeWorkflowIdled;332
workflowruntime.WorkflowPersisted -= workflowruntimeWorkflowPersisted;333
workflowruntime.WorkflowUnloaded -= workflowruntimeWorkflowUnloaded;334
workflowruntime.WorkflowCreated -= workflowruntimeWorkflowCreated;335
workflowruntime.WorkflowStarted -= workflowruntimeWorkflowStarted;336

337
#endregion338

339
tacked = false;340
}341
else342

{343
throw (new Exception("TrackingWorkflowEvent didn't initialized or TrackingInstanceEvent didn't tack event"));344
}345
}346
347
#endregion348

349

事件处理#region 事件处理350

351

runtime event#region runtime event352
void workflowRuntime_Started(object sender, WorkflowRuntimeEventArgs e)353

{354
Console.WriteLine("TrackingWorkflowEvent: Workflow runtime started(启动)\tDateTime(时间) : {1}.{2}", e.IsStarted, DateTime.Now, DateTime.Now.Millisecond);355
}356

357
void workflowRuntime_ServicesExceptionNotHandled(object sender, ServicesExceptionNotHandledEventArgs e)358

{359
Console.WriteLine("TrackingWorkflowEvent: Workflow runtime services exception not handled(异常)[{0}]\tDateTime(时间) : {1}.{2}", e.Exception, DateTime.Now, DateTime.Now.Millisecond);360
}361

362
void workflowRuntime_Stopped(object sender, WorkflowRuntimeEventArgs e)363

{364
dic.Clear();365
Console.WriteLine("TrackingWorkflowEvent: Workflow runtime stopped(停止)\tDateTime(时间) : {1}.{2}", e.IsStarted, DateTime.Now, DateTime.Now.Millisecond);366
}367
#endregion runtime event368

369

instance event#region instance event370
void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)371

{372
ChangeStatus(e.WorkflowInstance, WorkflowStatus.Completed);373
Console.WriteLine("TrackingWorkflowEvent: Workflow {0} \tcompleted(完成)\tDateTime(时间) : {1}.{2}", e.WorkflowInstance.InstanceId, DateTime.Now, DateTime.Now.Millisecond);374
}375

376
void workflowRuntime_WorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)377

{378
ChangeStatus(e.WorkflowInstance, WorkflowStatus.Terminated);379
Console.WriteLine("TrackingWorkflowEvent: Workflow {0} \tterminated(结束)\tDateTime(时间) : {1}.{2}\tmessage:{3}", e.WorkflowInstance.InstanceId, DateTime.Now, DateTime.Now.Millisecond, e.Exception.Message);380
}381

382
void workflowRuntime_WorkflowSuspended(object sender, WorkflowSuspendedEventArgs e)383

{384
ChangeStatus(e.WorkflowInstance, WorkflowStatus.Suspended);385
Console.WriteLine("TrackingWorkflowEvent: Workflow {0} \tsuspended(暂停)\tDateTime(时间) : {1}.{2}\tmessage:{3}", e.WorkflowInstance.InstanceId, DateTime.Now, DateTime.Now.Millisecond, e.Error);386
}387

388
void workflowRuntime_WorkflowResumed(object sender, WorkflowEventArgs e)389

{390
ChangeStatus(e.WorkflowInstance, WorkflowStatus.Running);391
Console.WriteLine("TrackingWorkflowEvent: Workflow {0} \tresumed(继续)\tDateTime(时间) : {1}.{2}", e.WorkflowInstance.InstanceId, DateTime.Now, DateTime.Now.Millisecond);392
}393

394
void workflowRuntime_WorkflowAborted(object sender, WorkflowEventArgs e)395

{396
ChangeStatus(e.WorkflowInstance, WorkflowStatus.Terminated);397
Console.WriteLine("TrackingWorkflowEvent: Workflow {0} \taborted(中断)\tDateTime(时间) : {1}.{2}", e.WorkflowInstance.InstanceId, DateTime.Now, DateTime.Now.Millisecond);398
}399

400
void workflowRuntime_WorkflowIdled(object sender, WorkflowEventArgs e)401

{402
ChangeStatus(e.WorkflowInstance, WorkflowStatus.Running);403
Console.WriteLine("TrackingWorkflowEvent: Workflow {0} \tidled(空闲)\tDateTime(时间) : {1}.{2}", e.WorkflowInstance.InstanceId, DateTime.Now, DateTime.Now.Millisecond);404
}405

406
void workflowRuntime_WorkflowUnloaded(object sender, WorkflowEventArgs e)407

{408
RemoveInstance(e.WorkflowInstance);409
Console.WriteLine("TrackingWorkflowEvent: Workflow {0} \tunloaded(卸载)\tDateTime(时间) : {1}.{2}", e.WorkflowInstance.InstanceId, DateTime.Now, DateTime.Now.Millisecond);410
}411

412
void workflowRuntime_WorkflowPersisted(object sender, WorkflowEventArgs e)413

{414
Console.WriteLine("TrackingWorkflowEvent: Workflow {0} \tpersisted(持久)\tDateTime(时间) : {1}.{2}", e.WorkflowInstance.InstanceId, DateTime.Now, DateTime.Now.Millisecond);415
}416

417
void workflowRuntime_WorkflowLoaded(object sender, WorkflowEventArgs e)418

{419
AddInstance(e.WorkflowInstance);420
Console.WriteLine("TrackingWorkflowEvent: Workflow {0} \tloaded(加载)\tDateTime(时间) : {1}.{2}", e.WorkflowInstance.InstanceId, DateTime.Now, DateTime.Now.Millisecond);421
}422

423
void workflowRuntime_WorkflowCreated(object sender, WorkflowEventArgs e)424

{425
AddInstance(e.WorkflowInstance, WorkflowStatus.Created);426
Console.WriteLine("TrackingWorkflowEvent: Workflow {0} \tcreated(创建)\tDateTime(时间) : {1}.{2}", e.WorkflowInstance.InstanceId, DateTime.Now, DateTime.Now.Millisecond);427
}428

429
void workflowRuntime_WorkflowStarted(object sender, WorkflowEventArgs e)430

{431
ChangeStatus(e.WorkflowInstance, WorkflowStatus.Running);432
Console.WriteLine("TrackingWorkflowEvent: Workflow {0} \tstarted(启动)\tDateTime(时间) : {1}.{2}", e.WorkflowInstance.InstanceId, DateTime.Now, DateTime.Now.Millisecond);433
}434

435

436
#endregion instance event437

438

439
#endregion 事件处理440

441
#endregion442

443

IDisposable Members#region IDisposable Members444

445
public void Dispose()446

{447
if (dic != null)448

{449
dic.Clear();450
dic = null;451
}452
}453

454
#endregion455
}456

457
}使用方便:
trackingworkflowevent = new TrackingWorkflowEvent(workflowRuntime); //创建
trackingworkflowevent.TackEvent(); //预订事件
trackingworkflowevent.GetWorkflowStatus(instance); //获取instance状态
trackingworkflowevent.UntackEvent(); //卸载事件
trackingworkflowevent.Dispose(); //消毁
trackingworkflowevent.TackEvent(); //预订事件
trackingworkflowevent.GetWorkflowStatus(instance); //获取instance状态
trackingworkflowevent.UntackEvent(); //卸载事件
trackingworkflowevent.Dispose(); //消毁