场景是这样的:
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事件,以便状态变化时处理
两个类:

TrackingStatus
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 WFDebugger
13

{
14
public class TrackingStatus
15
{
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 Instance
43
{
44
get
45
{
46
return instance;
47
}
48
}
49
50
public WorkflowStatus Status
51
{
52
get
53
{
54
return status;
55
}
56
}
57
58
public DateTime LastEventTime
59
{
60
get
61
{
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
else
88
{
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

TrackingWorkflowEvent
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 WFDebugger
17

{
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
#endregion
32
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
#endregion
43
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
else
55
{
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
else
65
{
66
throw (new Exception("Workflowruntime havn't WorkflowPersistenceService."));
67
}
68
69
//runtime event
70
workflowruntimeStarted = new EventHandler<WorkflowRuntimeEventArgs>(workflowRuntime_Started);
71
workflowruntimeServicesExceptionNotHandled = new EventHandler<ServicesExceptionNotHandledEventArgs>(workflowRuntime_ServicesExceptionNotHandled);
72
workflowruntimeStopped = new EventHandler<WorkflowRuntimeEventArgs>(workflowRuntime_Stopped);
73
74
//instance event
75
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
else
90
{
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
else
115
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
else
155
{
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
else
179
{
180
return false;
181
//return AddInstance(instance, status);
182
}
183
184
185
}
186
#endregion
187
188
公开属性#region 公开属性
189
/**//// <summary>
190
/// 工作流环境
191
/// </summary>
192
public WorkflowRuntime WorkflowRuntime
193
{
194
get
195
{
196
return workflowruntime;
197
}
198
}
199
200
/**//// <summary>
201
/// 实例数量
202
/// </summary>
203
public int Count
204
{
205
get
206
{
207
return dic.Count;
208
}
209
}
210
211
/**//// <summary>
212
/// 是否在跟踪
213
/// </summary>
214
public bool IsOnTracking
215
{
216
get
217
{
218
return tacked;
219
}
220
}
221
/**//// <summary>
222
/// 是否初始化
223
/// </summary>
224
public bool Initialized
225
{
226
get
227
{
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
else
242
{
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 Event
263
264
事件句柄#region 事件句柄
265
//runtime event
266
EventHandler<WorkflowRuntimeEventArgs> workflowruntimeStarted;
267
EventHandler<ServicesExceptionNotHandledEventArgs> workflowruntimeServicesExceptionNotHandled;
268
EventHandler<WorkflowRuntimeEventArgs> workflowruntimeStopped;
269
270
//instance event
271
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 event
289
workflowruntime.Started += workflowruntimeStarted;
290
workflowruntime.ServicesExceptionNotHandled += workflowruntimeServicesExceptionNotHandled;
291
workflowruntime.Stopped += workflowruntimeStopped;
292
293
//instance event
294
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
#endregion
306
tacked = true;
307
}
308
else
309
{
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 event
320
workflowruntime.Started -= workflowruntimeStarted;
321
workflowruntime.ServicesExceptionNotHandled -= workflowruntimeServicesExceptionNotHandled;
322
workflowruntime.Stopped -= workflowruntimeStopped;
323
324
//instance event
325
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
#endregion
338
339
tacked = false;
340
}
341
else
342
{
343
throw (new Exception("TrackingWorkflowEvent didn't initialized or TrackingInstanceEvent didn't tack event"));
344
}
345
}
346
347
#endregion
348
349
事件处理#region 事件处理
350
351
runtime event#region runtime event
352
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 event
368
369
instance event#region instance event
370
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 event
437
438
439
#endregion 事件处理
440
441
#endregion
442
443
IDisposable Members#region IDisposable Members
444
445
public void Dispose()
446
{
447
if (dic != null)
448
{
449
dic.Clear();
450
dic = null;
451
}
452
}
453
454
#endregion
455
}
456
457
}
使用方便:
trackingworkflowevent = new TrackingWorkflowEvent(workflowRuntime); //创建
trackingworkflowevent.TackEvent(); //预订事件
trackingworkflowevent.GetWorkflowStatus(instance); //获取instance状态
trackingworkflowevent.UntackEvent(); //卸载事件
trackingworkflowevent.Dispose(); //消毁