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
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5using System.Workflow;
6using System.Workflow.Runtime;
7using System.Workflow.Runtime.Hosting;
8using System.Workflow.Runtime.Tracking;
9using System.Workflow.Activities;
10using System.Workflow.ComponentModel;
11
12namespace 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
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5using System.Workflow;
6using System.Workflow.Runtime;
7using System.Workflow.Runtime.Hosting;
8using System.Workflow.Runtime.Tracking;
9using System.Workflow.Activities;
10using System.Workflow.ComponentModel;
11
12namespace 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
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Data;
5
6using System.Workflow;
7using System.Workflow.Runtime;
8using System.Workflow.Runtime.Hosting;
9using System.Workflow.Runtime.Tracking;
10using System.Workflow.Activities;
11using System.Workflow.ComponentModel;
12using System.Collections.ObjectModel;
13
14
15
16namespace 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}
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Data;
5
6using System.Workflow;
7using System.Workflow.Runtime;
8using System.Workflow.Runtime.Hosting;
9using System.Workflow.Runtime.Tracking;
10using System.Workflow.Activities;
11using System.Workflow.ComponentModel;
12using System.Collections.ObjectModel;
13
14
15
16namespace 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(); //消毁
trackingworkflowevent.TackEvent(); //预订事件
trackingworkflowevent.GetWorkflowStatus(instance); //获取instance状态
trackingworkflowevent.UntackEvent(); //卸载事件
trackingworkflowevent.Dispose(); //消毁