1 #pragma warning disable 1634, 1691
2 
3 namespace System.Workflow.ComponentModel
4 {
5     #region Imports
6 
7     using System;
8     using System.Collections.Generic;
9     using System.Text;
10     using System.Collections;
11     using System.Runtime.Serialization;
12     using System.Security.Permissions;
13     using System.Diagnostics;
14     using System.Workflow.ComponentModel.Design;
15 
16     #endregion
17 
18     [Serializable]
19     [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
20     public class QueueEventArgs : EventArgs
21     {
22         IComparable queueName;
23 
QueueEventArgs(IComparable queueName)24         internal QueueEventArgs(IComparable queueName)
25         {
26             this.queueName = queueName;
27         }
28 
29         public IComparable QueueName
30         {
31             get
32             {
33                 return this.queueName;
34             }
35         }
36     }
37 
38     [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
39     public sealed class ActivityExecutionContext : IServiceProvider, IDisposable
40     {
41         #region Data members
42 
43         // dependency props
44         public static readonly DependencyProperty CurrentExceptionProperty = DependencyProperty.RegisterAttached("CurrentException", typeof(Exception), typeof(ActivityExecutionContext), new PropertyMetadata(null, DependencyPropertyOptions.Default, null, EnforceExceptionSemantics, true));
45         internal static readonly DependencyProperty GrantedLocksProperty = DependencyProperty.RegisterAttached("GrantedLocks", typeof(Dictionary<string, GrantedLock>), typeof(ActivityExecutionContext));
46         internal static readonly DependencyProperty CachedGrantedLocksProperty = DependencyProperty.RegisterAttached("CachedGrantedLocks", typeof(Dictionary<string, GrantedLock>), typeof(ActivityExecutionContext), new PropertyMetadata(DependencyPropertyOptions.NonSerialized));
47         internal static readonly DependencyProperty LockAcquiredCallbackProperty = DependencyProperty.RegisterAttached("LockAcquiredCallback", typeof(ActivityExecutorDelegateInfo<EventArgs>), typeof(ActivityExecutionContext));
48 
49         private Activity currentActivity = null;
50         private ActivityExecutionContextManager contextManager = null;
51         private IStartWorkflow startWorkflowService = null;
52         private bool allowSignalsOnCurrentActivity = false;
53 
54         private static Type schedulerServiceType = Type.GetType("System.Workflow.Runtime.Hosting.WorkflowSchedulerService, " + AssemblyRef.RuntimeAssemblyRef);
55         private static Type persistenceServiceType = Type.GetType("System.Workflow.Runtime.Hosting.WorkflowPersistenceService, " + AssemblyRef.RuntimeAssemblyRef);
56         private static Type trackingServiceType = Type.GetType("System.Workflow.Runtime.Tracking.TrackingService, " + AssemblyRef.RuntimeAssemblyRef);
57         private static Type transactionServiceType = Type.GetType("System.Workflow.Runtime.Hosting.WorkflowCommitWorkBatchService, " + AssemblyRef.RuntimeAssemblyRef);
58         private static Type loaderServiceType = Type.GetType("System.Workflow.Runtime.Hosting.WorkflowLoaderService, " + AssemblyRef.RuntimeAssemblyRef);
59 
60         #endregion
61 
62         #region Members
63 
ActivityExecutionContext(Activity activity)64         internal ActivityExecutionContext(Activity activity)
65         {
66             this.currentActivity = activity;
67         }
ActivityExecutionContext(Activity activity, bool allowSignalsOnCurrentActivity)68         internal ActivityExecutionContext(Activity activity, bool allowSignalsOnCurrentActivity)
69             : this(activity)
70         {
71             // ExecuteActivity/FaultActivity on root activity will be called by the ScheduleExecutor
72             // we don't want to do child check in that case, so this flag is just to avoid those checks
73             this.allowSignalsOnCurrentActivity = allowSignalsOnCurrentActivity;
74         }
75 
76         public Activity Activity
77         {
78             get
79             {
80                 if (this.currentActivity == null)
81 #pragma warning suppress 56503
82                     throw new ObjectDisposedException("ActivityExecutionContext");
83 
84                 return this.currentActivity;
85             }
86         }
87 
88         public ActivityExecutionContextManager ExecutionContextManager
89         {
90             get
91             {
92                 if (this.currentActivity == null)
93 #pragma warning suppress 56503
94                     throw new ObjectDisposedException("ActivityExecutionContext");
95 
96                 if (this.contextManager == null)
97                     this.contextManager = new ActivityExecutionContextManager(this);
98 
99                 return this.contextManager;
100             }
101         }
102 
103         #endregion
104 
105         #region StartWorkflow
106         internal sealed class StartWorkflow : IStartWorkflow
107         {
108             private ActivityExecutionContext executionContext = null;
StartWorkflow(ActivityExecutionContext executionContext)109             internal StartWorkflow(ActivityExecutionContext executionContext)
110             {
111                 this.executionContext = executionContext;
112             }
IStartWorkflow.StartWorkflow(Type workflowType, Dictionary<string, object> namedArgumentValues)113             Guid IStartWorkflow.StartWorkflow(Type workflowType, Dictionary<string, object> namedArgumentValues)
114             {
115                 return this.executionContext.WorkflowCoreRuntime.StartWorkflow(workflowType, namedArgumentValues);
116             }
117         }
118         #endregion
119 
120         #region IServiceProvider methods
121 
GetService()122         public T GetService<T>()
123         {
124             return (T)this.GetService(typeof(T));
125         }
126 
GetService(Type serviceType)127         public Object GetService(Type serviceType)
128         {
129             if (this.currentActivity == null)
130                 throw new ObjectDisposedException("ActivityExecutionContext");
131 
132             if (serviceType == typeof(IStartWorkflow))
133             {
134                 if (this.startWorkflowService == null)
135                     this.startWorkflowService = new StartWorkflow(this);
136 
137                 return this.startWorkflowService;
138             }
139             else
140             {
141                 if (schedulerServiceType != null && schedulerServiceType.IsAssignableFrom(serviceType))
142                     return null;
143 
144                 if (persistenceServiceType != null && persistenceServiceType.IsAssignableFrom(serviceType))
145                     return null;
146 
147                 if (trackingServiceType != null && trackingServiceType.IsAssignableFrom(serviceType))
148                     return null;
149 
150                 if (transactionServiceType != null && transactionServiceType.IsAssignableFrom(serviceType))
151                     return null;
152 
153                 if (loaderServiceType != null && loaderServiceType.IsAssignableFrom(serviceType))
154                     return null;
155             }
156 
157             return this.currentActivity.WorkflowCoreRuntime.GetService(this.currentActivity, serviceType);
158         }
159 
160         #endregion
161 
162         #region Context Information
163 
164         public Guid ContextGuid
165         {
166             get
167             {
168                 if (this.currentActivity == null)
169 #pragma warning suppress 56503
170                     throw new ObjectDisposedException("ActivityExecutionContext");
171 
172                 return this.currentActivity.ContextActivity.ContextGuid;
173             }
174         }
175         internal int ContextId
176         {
177             get
178             {
179                 if (this.currentActivity == null)
180 #pragma warning suppress 56503
181                     throw new ObjectDisposedException("ActivityExecutionContext");
182 
183                 return this.currentActivity.ContextActivity.ContextId;
184             }
185         }
186 
187         #endregion
188 
189         #region Activity Execution Signals
190 
InitializeActivity(Activity activity)191         internal void InitializeActivity(Activity activity)
192         {
193             if (this.currentActivity == null)
194                 throw new ObjectDisposedException("ActivityExecutionContext");
195 
196             if (activity == null)
197                 throw new ArgumentNullException("activity");
198 
199             if (!IsValidChild(activity, false))
200                 throw new ArgumentException(SR.GetString(SR.AEC_InvalidActivity), "activity");
201 
202             if (activity.ExecutionStatus != ActivityExecutionStatus.Initialized)
203                 throw new InvalidOperationException(SR.GetString(SR.Error_InvalidInitializingState));
204 
205             using (ActivityExecutionContext executionContext = new ActivityExecutionContext(activity))
206             {
207                 using (this.currentActivity.WorkflowCoreRuntime.SetCurrentActivity(activity))
208                     activity.Initialize(executionContext);
209             }
210         }
ExecuteActivity(Activity activity)211         public void ExecuteActivity(Activity activity)
212         {
213             if (this.currentActivity == null)
214                 throw new ObjectDisposedException("ActivityExecutionContext");
215 
216             if (activity == null)
217                 throw new ArgumentNullException("activity");
218 
219             // if this activity is not executing, canceling, faulting OR compensating
220             // then it can not execute a child.
221             if (!this.allowSignalsOnCurrentActivity &&
222                     (
223                     this.currentActivity.WorkflowCoreRuntime.CurrentActivity.ExecutionStatus == ActivityExecutionStatus.Initialized ||
224                     this.currentActivity.WorkflowCoreRuntime.CurrentActivity.ExecutionStatus == ActivityExecutionStatus.Closed
225                     )
226                 )
227                 throw new InvalidOperationException(SR.GetString(SR.Error_InvalidStateToExecuteChild));
228 
229             if (!IsValidChild(activity, false))
230                 throw new ArgumentException(SR.GetString(SR.AEC_InvalidActivity), "activity");
231 
232             if (activity.ExecutionStatus != ActivityExecutionStatus.Initialized)
233                 throw new InvalidOperationException(SR.GetString(SR.Error_InvalidExecutionState));
234 
235             try
236             {
237                 activity.SetStatus(ActivityExecutionStatus.Executing, false);
238             }
239             finally
240             {
241                 Debug.Assert(activity.ExecutionStatus == ActivityExecutionStatus.Executing);
242                 this.currentActivity.WorkflowCoreRuntime.ScheduleItem(new ActivityExecutorOperation(activity, ActivityOperationType.Execute, this.ContextId), IsInAtomicTransaction(activity), false, false);
243             }
244         }
CancelActivity(Activity activity)245         public void CancelActivity(Activity activity)
246         {
247             if (this.currentActivity == null)
248                 throw new ObjectDisposedException("ActivityExecutionContext");
249 
250             if (activity == null)
251                 throw new ArgumentNullException("activity");
252 
253             // if this activity is not executing, canceling, faulting OR compensating
254             // then it can not cancel a child.
255             if (!this.allowSignalsOnCurrentActivity &&
256                     (
257                     this.currentActivity.WorkflowCoreRuntime.CurrentActivity.ExecutionStatus == ActivityExecutionStatus.Initialized ||
258                     this.currentActivity.WorkflowCoreRuntime.CurrentActivity.ExecutionStatus == ActivityExecutionStatus.Closed
259                     )
260                 )
261                 throw new InvalidOperationException(SR.GetString(SR.Error_InvalidStateToExecuteChild));
262 
263             if (!IsValidChild(activity, false))
264                 throw new ArgumentException(SR.GetString(SR.AEC_InvalidActivity), "activity");
265 
266             if (activity.ExecutionStatus != ActivityExecutionStatus.Executing)
267                 throw new InvalidOperationException(SR.GetString(SR.Error_InvalidCancelingState));
268 
269             try
270             {
271                 activity.SetStatus(ActivityExecutionStatus.Canceling, false);
272             }
273             finally
274             {
275                 this.currentActivity.WorkflowCoreRuntime.ScheduleItem(new ActivityExecutorOperation(activity, ActivityOperationType.Cancel, this.ContextId), IsInAtomicTransaction(activity), false, false);
276             }
277         }
CompensateActivity(Activity activity)278         internal void CompensateActivity(Activity activity)
279         {
280             if (this.currentActivity == null)
281                 throw new ObjectDisposedException("ActivityExecutionContext");
282 
283             if (activity == null)
284                 throw new ArgumentNullException("activity");
285 
286             if (!IsValidNestedChild(activity))
287                 throw new ArgumentException(SR.GetString(SR.AEC_InvalidNestedActivity), "activity");
288 
289             if (activity.ExecutionStatus != ActivityExecutionStatus.Closed)
290                 throw new InvalidOperationException(SR.GetString(SR.Error_InvalidCompensatingState));
291 
292             try
293             {
294                 activity.SetStatus(ActivityExecutionStatus.Compensating, false);
295             }
296             finally
297             {
298                 this.currentActivity.WorkflowCoreRuntime.ScheduleItem(new ActivityExecutorOperation(activity, ActivityOperationType.Compensate, this.ContextId), IsInAtomicTransaction(activity), false, false);
299             }
300         }
FaultActivity(Exception e)301         internal void FaultActivity(Exception e)
302         {
303             if (this.currentActivity == null)
304                 throw new ObjectDisposedException("ActivityExecutionContext");
305 
306             // the current activity might have closed, in that case, we would like to give the exception to parent
307             if (this.currentActivity.ExecutionStatus == ActivityExecutionStatus.Closed)
308             {
309                 if (this.currentActivity.Parent == null)
310                 {
311                     // this could have happened if the root activity closed, but
312                     // then it threw an exception
313                     this.currentActivity.WorkflowCoreRuntime.TerminateInstance(e);
314                 }
315                 else
316                 {
317                     this.currentActivity.WorkflowCoreRuntime.RaiseException(e, this.currentActivity.Parent, string.Empty);
318                 }
319             }
320             else
321             {
322                 try
323                 {
324                     this.currentActivity.SetValueCommon(CurrentExceptionProperty, e, CurrentExceptionProperty.DefaultMetadata, false);
325                     this.currentActivity.SetStatus(ActivityExecutionStatus.Faulting, false);
326                 }
327                 finally
328                 {
329                     this.currentActivity.WorkflowCoreRuntime.ScheduleItem(new ActivityExecutorOperation(this.currentActivity, ActivityOperationType.HandleFault, this.ContextId, e), IsInAtomicTransaction(this.currentActivity), false, false);
330                 }
331             }
332         }
333 
CloseActivity()334         public void CloseActivity()
335         {
336             if (this.currentActivity == null)
337                 throw new ObjectDisposedException("ActivityExecutionContext");
338 
339             switch (this.currentActivity.ExecutionStatus)
340             {
341                 case ActivityExecutionStatus.Executing:
342                     this.currentActivity.MarkCompleted();
343                     break;
344                 case ActivityExecutionStatus.Canceling:
345                     this.currentActivity.MarkCanceled();
346                     break;
347                 case ActivityExecutionStatus.Compensating:
348                     this.currentActivity.MarkCompensated();
349                     break;
350                 case ActivityExecutionStatus.Faulting:
351                     this.currentActivity.MarkFaulted();
352                     break;
353                 case ActivityExecutionStatus.Closed:
354                     break;
355                 default:
356                     throw new InvalidOperationException(SR.GetString(SR.Error_InvalidClosingState));
357             }
358         }
359 
360         internal void Invoke<T>(EventHandler<T> handler, T e) where T : EventArgs
361         {
362             if (this.currentActivity == null)
363                 throw new ObjectDisposedException("ActivityExecutionContext");
364 
365             // let the activity handle it
366             this.currentActivity.Invoke(handler, e);
367         }
368 
369         #endregion
370 
371         #region Tracking Method
372 
373         // user tracking
TrackData(object userData)374         public void TrackData(object userData)
375         {
376             if (this.currentActivity == null)
377                 throw new ObjectDisposedException("ActivityExecutionContext");
378 
379             if (null == userData)
380                 throw new ArgumentNullException("userData");
381 
382             this.currentActivity.WorkflowCoreRuntime.Track(null, userData);
383         }
384 
385         // user tracking
TrackData(string userDataKey, object userData)386         public void TrackData(string userDataKey, object userData)
387         {
388             if (this.currentActivity == null)
389                 throw new ObjectDisposedException("ActivityExecutionContext");
390 
391             if (null == userData)
392                 throw new ArgumentNullException("userData");
393 
394             this.currentActivity.WorkflowCoreRuntime.Track(userDataKey, userData);
395         }
396 
397         #endregion
398 
399         #region Locking methods
400 
AcquireLocks(IActivityEventListener<EventArgs> locksAcquiredCallback)401         internal bool AcquireLocks(IActivityEventListener<EventArgs> locksAcquiredCallback)
402         {
403             if (this.currentActivity == null)
404                 throw new ObjectDisposedException("ActivityExecutionContext");
405 
406             this.Activity.SetValue(LockAcquiredCallbackProperty, new ActivityExecutorDelegateInfo<EventArgs>(true, locksAcquiredCallback, this.Activity.ContextActivity));
407             return AcquireLocks(this.Activity);
408         }
409 
AcquireLocks(Activity activity)410         private bool AcquireLocks(Activity activity)
411         {
412             // If this activity doesn't have any handles, we have nothing to do.
413             ICollection<string> handles = GetAllSynchronizationHandles(activity);
414             if (handles == null || handles.Count == 0)
415                 return true;
416 
417             Activity parent = activity.Parent;
418             while (parent != null)
419             {
420                 if (parent.SupportsSynchronization || parent.Parent == null)
421                 {
422                     Dictionary<string, GrantedLock> grantedLocks = (Dictionary<string, GrantedLock>)parent.GetValue(GrantedLocksProperty);
423                     if (grantedLocks == null)
424                     {
425                         grantedLocks = new Dictionary<string, GrantedLock>();
426                         parent.SetValue(GrantedLocksProperty, grantedLocks);
427                     }
428                     foreach (string handle in handles)
429                     {
430                         bool acquiredLocks = true;
431                         if (!grantedLocks.ContainsKey(handle))
432                         {
433                             grantedLocks[handle] = new GrantedLock(activity);
434                         }
435                         else if (grantedLocks[handle].Holder != activity)
436                         {
437                             grantedLocks[handle].WaitList.Add(activity);
438                             acquiredLocks = false;
439                         }
440                         if (!acquiredLocks)
441                             return false;
442                     }
443                 }
444 
445                 // If we reach a parent which has at least one handle, then we do not need to
446                 // go any further as the parent would already have acquired all our locks for
447                 // itself. Note that we still need to acquire our locks in the same parent if
448                 // the parent ProvidesSychronization, hence, this if check is *not* after
449                 // "parent = parent.Parent"!
450                 ICollection<string> synchronizationHandlesOnParent = (ICollection<string>)parent.GetValue(Activity.SynchronizationHandlesProperty);
451                 if (synchronizationHandlesOnParent != null && synchronizationHandlesOnParent.Count != 0)
452                     break;
453 
454                 parent = parent.Parent;
455             }
456             return true;
457         }
458 
ReleaseLocks(bool transactional)459         internal void ReleaseLocks(bool transactional)
460         {
461             if (this.currentActivity == null)
462                 throw new ObjectDisposedException("ActivityExecutionContext");
463 
464 
465             // remove the callback.
466             this.Activity.RemoveProperty(LockAcquiredCallbackProperty);
467 
468             // The assumption is that lock contentions will be few. Hence, we optimize serialization
469             // size over performance, for ex. do not persist the list of locks that have already been
470             // granted.
471             ICollection<string> handles = GetAllSynchronizationHandles(this.Activity);
472             if (handles == null || handles.Count == 0)
473                 return;
474 
475             List<Activity> waitingActivities = new List<Activity>();
476             Activity parent = Activity.Parent;
477             while (parent != null)
478             {
479                 if (parent.SupportsSynchronization || parent.Parent == null)
480                 {
481                     Dictionary<string, GrantedLock> grantedLocks = (Dictionary<string, GrantedLock>)parent.GetValue(GrantedLocksProperty);
482 
483                     // if its an transactional release of locks, then release it and then keep it
484                     // cached, so that in case of rollback, we can reacuire locks
485                     if (transactional)
486                     {
487                         Dictionary<string, GrantedLock> cachedGrantedLocks = new Dictionary<string, GrantedLock>();
488 
489                         if (grantedLocks != null)
490                             foreach (KeyValuePair<string, GrantedLock> grantedLockEntry in grantedLocks)
491                                 cachedGrantedLocks.Add(grantedLockEntry.Key, (GrantedLock)grantedLockEntry.Value.Clone());
492 
493                         parent.SetValue(CachedGrantedLocksProperty, cachedGrantedLocks);
494                     }
495 
496                     if (grantedLocks != null)
497                     {
498                         foreach (string handle in handles)
499                         {
500                             if (!grantedLocks.ContainsKey(handle))
501                             {
502                                 continue;
503                             }
504                             else if (grantedLocks[handle].WaitList.Count == 0)
505                             {
506                                 grantedLocks.Remove(handle);
507                             }
508                             else if (grantedLocks[handle].Holder != this.Activity)
509                             {
510                                 grantedLocks[handle].WaitList.Remove(this.Activity);
511                             }
512                             else
513                             {
514                                 // Grant the lock to the next waiting activity.
515                                 Activity waitingActivity = grantedLocks[handle].WaitList[0];
516                                 grantedLocks[handle].WaitList.RemoveAt(0);
517                                 grantedLocks[handle].Holder = waitingActivity;
518                                 if (!waitingActivities.Contains(waitingActivity))
519                                     waitingActivities.Add(waitingActivity);
520                             }
521                         }
522                         if (grantedLocks.Count == 0)
523                             parent.RemoveProperty(GrantedLocksProperty);
524                     }
525                 }
526 
527                 // If we reach a parent which has at least one handle, then we do not need to
528                 // go any further as the parent would already have acquired all our locks for
529                 // itself. Note that we still need to acquire our locks in the same parent if
530                 // the parent ProvidesSychronization, hence, this if check is *not* after
531                 // "parent = parent.Parent"!
532                 ICollection<string> synchronizationHandlesOnParent = (ICollection<string>)parent.GetValue(Activity.SynchronizationHandlesProperty);
533                 if (synchronizationHandlesOnParent != null && synchronizationHandlesOnParent.Count != 0)
534                     break;
535 
536                 parent = parent.Parent;
537             }
538 
539             // Try and acquire locks for all the waiting activities.
540             foreach (Activity waitingActivity in waitingActivities)
541             {
542                 if (AcquireLocks(waitingActivity))
543                 {
544                     ActivityExecutorDelegateInfo<EventArgs> waitingActivityCallback = (ActivityExecutorDelegateInfo<EventArgs>)waitingActivity.GetValue(LockAcquiredCallbackProperty);
545                     waitingActivityCallback.InvokeDelegate(this.Activity.ContextActivity, EventArgs.Empty, false, transactional);
546                 }
547             }
548         }
549 
GetAllSynchronizationHandles(Activity activity)550         private ICollection<string> GetAllSynchronizationHandles(Activity activity)
551         {
552             // If the activity doesn't have any handles, do not look at child activities.
553             ICollection<string> handleCollection = (ICollection<string>)activity.GetValue(Activity.SynchronizationHandlesProperty);
554             if (handleCollection == null || handleCollection.Count == 0)
555                 return handleCollection;
556 
557             List<string> handles = new List<string>(handleCollection);
558             // Collect all child locks and normalize the list.
559             if (activity is CompositeActivity)
560             {
561                 Walker walker = new Walker();
562                 walker.FoundActivity += delegate(Walker w, WalkerEventArgs e)
563                 {
564                     if (e.CurrentActivity == activity)
565                         return;
566 
567                     ICollection<string> handlesOnChild = (ICollection<string>)e.CurrentActivity.GetValue(Activity.SynchronizationHandlesProperty);
568                     if (handlesOnChild != null)
569                         handles.AddRange(handlesOnChild);
570                 };
571                 walker.Walk(activity);
572             }
573 
574             // normalize handles
575             handles.Sort();
576             for (int i = 1; i < handles.Count; i++)
577             {
578                 if (handles[i] == handles[i - 1])
579                     handles.RemoveAt(--i);
580             }
581             handles.TrimExcess();
582 
583             // return
584             return handles;
585         }
586 
587         #endregion
588 
589         #region Instance Operation Methods
590 
SuspendWorkflowInstance(string suspendDescription)591         internal void SuspendWorkflowInstance(string suspendDescription)
592         {
593             if (this.currentActivity == null)
594                 throw new ObjectDisposedException("ActivityExecutionContext");
595 
596             this.currentActivity.WorkflowCoreRuntime.SuspendInstance(suspendDescription);
597         }
TerminateWorkflowInstance(Exception e)598         internal void TerminateWorkflowInstance(Exception e)
599         {
600             if (this.currentActivity == null)
601                 throw new ObjectDisposedException("ActivityExecutionContext");
602 
603             if (e == null)
604                 throw new ArgumentNullException("e");
605 
606             this.currentActivity.WorkflowCoreRuntime.TerminateInstance(e);
607         }
CheckpointInstanceState()608         internal void CheckpointInstanceState()
609         {
610             if (this.currentActivity == null)
611                 throw new ObjectDisposedException("ActivityExecutionContext");
612 
613             this.currentActivity.WorkflowCoreRuntime.CheckpointInstanceState(this.currentActivity);
614         }
RequestRevertToCheckpointState(EventHandler<EventArgs> handler, EventArgs data, bool suspendOnRevert, string suspendOnRevertInfo)615         internal void RequestRevertToCheckpointState(EventHandler<EventArgs> handler, EventArgs data, bool suspendOnRevert, string suspendOnRevertInfo)
616         {
617             if (this.currentActivity == null)
618                 throw new ObjectDisposedException("ActivityExecutionContext");
619 
620             this.currentActivity.WorkflowCoreRuntime.RequestRevertToCheckpointState(this.currentActivity, handler, data, suspendOnRevert, suspendOnRevertInfo);
621         }
DisposeCheckpointState()622         internal void DisposeCheckpointState()
623         {
624             if (this.currentActivity == null)
625                 throw new ObjectDisposedException("ActivityExecutionContext");
626 
627             this.currentActivity.WorkflowCoreRuntime.DisposeCheckpointState();
628         }
629         #endregion
630 
631         #region Helper Methods
632 
IsValidChild(Activity activity, bool allowContextVariance)633         internal bool IsValidChild(Activity activity, bool allowContextVariance)
634         {
635             if (this.currentActivity == null)
636                 throw new ObjectDisposedException("ActivityExecutionContext");
637 
638             if (activity == this.currentActivity.WorkflowCoreRuntime.CurrentActivity && this.allowSignalsOnCurrentActivity)
639                 return true;
640 
641             if (activity.Enabled && activity.Parent == this.currentActivity.WorkflowCoreRuntime.CurrentActivity && (allowContextVariance || activity.Equals(this.Activity.GetActivityByName(activity.QualifiedName, true))))
642                 return true;
643 
644             return false;
645         }
IsValidNestedChild(Activity activity)646         internal bool IsValidNestedChild(Activity activity)
647         {
648             if (this.currentActivity == null)
649                 throw new ObjectDisposedException("ActivityExecutionContext");
650 
651             if (activity == this.currentActivity)
652                 return true;
653 
654             Activity parentActivity = activity;
655             while (parentActivity != null && parentActivity.Enabled && parentActivity.Parent != this.currentActivity.ContextActivity)
656                 parentActivity = parentActivity.Parent;
657 
658             return (parentActivity != null && parentActivity.Enabled);
659         }
660         internal IWorkflowCoreRuntime WorkflowCoreRuntime
661         {
662             get
663             {
664                 if (this.currentActivity == null)
665 #pragma warning suppress 56503
666                     throw new ObjectDisposedException("ActivityExecutionContext");
667 
668                 return this.GetService<IWorkflowCoreRuntime>();
669             }
670         }
IsInAtomicTransaction(Activity activity)671         internal static bool IsInAtomicTransaction(Activity activity)
672         {
673             bool isInAtomicTransaction = false;
674             while (activity != null)
675             {
676                 if (activity == activity.WorkflowCoreRuntime.CurrentAtomicActivity)
677                 {
678                     isInAtomicTransaction = true;
679                     break;
680                 }
681                 activity = activity.Parent;
682             }
683             return isInAtomicTransaction;
684         }
685         #endregion
686 
687         #region CurrentExceptionProperty Guard
EnforceExceptionSemantics(DependencyObject d, object value)688         static void EnforceExceptionSemantics(DependencyObject d, object value)
689         {
690             Activity activity = d as Activity;
691 
692             if (activity == null)
693                 throw new ArgumentException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_DOIsNotAnActivity));
694 
695             if (value != null)
696                 throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_PropertyCanBeOnlyCleared));
697 
698             d.SetValueCommon(CurrentExceptionProperty, null, CurrentExceptionProperty.DefaultMetadata, false);
699         }
700         #endregion
701 
702         #region IDisposable Members
703 
IDisposable.Dispose()704         void IDisposable.Dispose()
705         {
706             if (this.currentActivity != null)
707             {
708                 if (this.contextManager != null)
709                 {
710                     this.contextManager.Dispose();
711                     this.contextManager = null;
712                 }
713                 this.currentActivity = null;
714             }
715         }
716 
717         #endregion
718     }
719 
720     #region Class GrantedLock
721 
722     [Serializable]
723     internal class GrantedLock : ICloneable
724     {
725         private Activity holder;
726         private List<Activity> waitList;
727 
GrantedLock(Activity holder)728         public GrantedLock(Activity holder)
729         {
730             this.holder = holder;
731             this.waitList = new List<Activity>();
732         }
733         public Activity Holder
734         {
735             get
736             {
737                 return this.holder;
738             }
739             set
740             {
741                 this.holder = value;
742             }
743         }
744         public IList<Activity> WaitList
745         {
746             get
747             {
748                 return this.waitList;
749             }
750         }
751 
752         #region ICloneable Members
753 
Clone()754         public object Clone()
755         {
756             GrantedLock clonedGrantedLock = new GrantedLock(this.holder);
757             clonedGrantedLock.waitList.InsertRange(0, this.waitList);
758             return clonedGrantedLock;
759         }
760         #endregion
761     }
762 
763     #endregion
764 }
765