1 // ****************************************************************************
2 // Copyright (C) Microsoft Corporation. All rights reserved.
7 using System
.Threading
;
8 using System
.Diagnostics
;
9 using System
.Globalization
;
10 using System
.Collections
;
11 using System
.Collections
.Generic
;
12 using System
.Collections
.ObjectModel
;
14 using System
.Workflow
.Runtime
;
15 using System
.Workflow
.ComponentModel
;
16 using System
.Workflow
.Runtime
.Hosting
;
18 namespace System
.Workflow
.Runtime
21 /// Schedule Instance handed over to the client
23 [Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
24 public sealed class WorkflowInstance
26 private WorkflowRuntime _runtime
;
27 private Guid _instanceId
;
28 private WorkflowExecutor _deadWorkflow
;
30 internal WorkflowInstance(Guid instanceId
, WorkflowRuntime workflowRuntime
)
32 if (instanceId
== Guid
.Empty
)
33 throw new ArgumentException(String
.Format(CultureInfo
.CurrentCulture
, ExecutionStringManager
.CantBeEmptyGuid
, "instanceId"));
34 if (workflowRuntime
== null)
35 throw new ArgumentNullException("workflowRuntime");
37 this._instanceId
= instanceId
;
38 this._runtime
= workflowRuntime
;
41 public Guid InstanceId
49 public WorkflowRuntime WorkflowRuntime
57 internal WorkflowExecutor DeadWorkflow
61 Debug
.Assert(value.WorkflowStatus
== WorkflowStatus
.Completed
|| value.WorkflowStatus
== WorkflowStatus
.Terminated
,
62 "Dead workflow is not dead.");
63 _deadWorkflow
= value;
67 public ReadOnlyCollection
<WorkflowQueueInfo
> GetWorkflowQueueData()
69 if (_deadWorkflow
!= null)
70 return _deadWorkflow
.GetWorkflowQueueInfos();
74 WorkflowExecutor executor
= _runtime
.Load(this);
75 if (executor
.IsInstanceValid
)
79 return executor
.GetWorkflowQueueInfos();
81 catch (InvalidOperationException
)
83 if (executor
.IsInstanceValid
)
90 public DateTime
GetWorkflowNextTimerExpiration()
94 WorkflowExecutor executor
= _runtime
.Load(this);
95 if (executor
.IsInstanceValid
)
99 return executor
.GetWorkflowNextTimerExpiration();
101 catch (InvalidOperationException
)
103 if (executor
.IsInstanceValid
)
110 public Activity
GetWorkflowDefinition()
114 WorkflowExecutor executor
= _runtime
.Load(this);
115 if (executor
.IsInstanceValid
)
119 // Make sure to get the clone here since the
120 // definition is mutable and shared across all
122 return executor
.GetWorkflowDefinitionClone("");
124 catch (InvalidOperationException
)
126 if (executor
.IsInstanceValid
)
135 using (new WorkflowTraceTransfer(this.InstanceId
))
137 this._runtime
.Load(this);
141 public bool TryUnload()
143 using (new WorkflowTraceTransfer(this.InstanceId
))
145 WorkflowExecutor executor
= _runtime
.Load(this);
146 using (executor
.ExecutorLock
.Enter())
148 if (executor
.IsInstanceValid
)
152 return executor
.TryUnload();
154 catch (InvalidOperationException
)
156 if (executor
.IsInstanceValid
)
165 public void Suspend(string error
)
167 using (new WorkflowTraceTransfer(this.InstanceId
))
171 WorkflowExecutor executor
= _runtime
.Load(this);
172 if (executor
.IsInstanceValid
)
174 if (executor
.WorkflowStatus
== WorkflowStatus
.Created
)
175 throw new InvalidOperationException(ExecutionStringManager
.CannotSuspendBeforeStart
);
178 executor
.Suspend(error
);
181 catch (InvalidOperationException
)
183 if (executor
.IsInstanceValid
)
186 catch (ExecutorLocksHeldException e
)
192 catch (ObjectDisposedException
)
194 // If an ObjectDisposedException is thrown because
195 // the WaitHandle has already closed, nothing to worry
206 using (new WorkflowTraceTransfer(this.InstanceId
))
208 if (_runtime
== null || _runtime
.GetService
<WorkflowPersistenceService
>() == null)
209 throw new InvalidOperationException(String
.Format(CultureInfo
.CurrentCulture
, ExecutionStringManager
.MissingPersistenceService
, this.InstanceId
));
212 WorkflowExecutor executor
= _runtime
.Load(this);
213 if (executor
.IsInstanceValid
)
220 catch (InvalidOperationException
)
222 if (executor
.IsInstanceValid
)
225 catch (ExecutorLocksHeldException e
)
229 e
.Handle
.WaitOne(/* maybe should have a timeout here?*/);
231 catch (ObjectDisposedException
)
233 // If an ObjectDisposedException is thrown because
234 // the WaitHandle has already closed, nothing to worry
245 using (new WorkflowTraceTransfer(this.InstanceId
))
249 WorkflowExecutor executor
= _runtime
.Load(this);
250 if (executor
.IsInstanceValid
)
257 catch (InvalidOperationException
)
259 if (executor
.IsInstanceValid
)
267 internal void ProcessTimers(object ignored
)
272 internal void ProcessTimers()
274 using (new WorkflowTraceTransfer(this.InstanceId
))
278 WorkflowExecutor executor
= null;
281 executor
= _runtime
.Load(this);
283 catch (InvalidOperationException
)
287 if (executor
!= null && executor
.IsInstanceValid
)
291 executor
.DeliverTimerSubscriptions();
294 catch (InvalidOperationException
)
296 if (executor
.IsInstanceValid
)
304 public void Terminate(string error
)
306 using (new WorkflowTraceTransfer(this.InstanceId
))
310 WorkflowExecutor executor
= _runtime
.Load(this);
311 if (executor
.IsInstanceValid
)
315 executor
.Terminate(error
);
318 catch (InvalidOperationException
)
320 if (executor
.IsInstanceValid
)
330 using (new WorkflowTraceTransfer(this.InstanceId
))
334 WorkflowExecutor executor
= _runtime
.Load(this);
335 if (executor
.IsInstanceValid
)
337 if (executor
.WorkflowStatus
== WorkflowStatus
.Created
)
338 throw new InvalidOperationException(ExecutionStringManager
.CannotAbortBeforeStart
);
345 catch (InvalidOperationException
)
347 if (executor
.IsInstanceValid
)
355 public void ReloadTrackingProfiles()
357 using (new WorkflowTraceTransfer(this.InstanceId
))
361 WorkflowExecutor executor
= _runtime
.Load(this);
362 if (executor
.IsInstanceValid
)
366 _runtime
.TrackingListenerFactory
.ReloadProfiles(executor
);
369 catch (InvalidOperationException
)
371 if (executor
.IsInstanceValid
)
379 public void ApplyWorkflowChanges(WorkflowChanges workflowChanges
)
381 using (new WorkflowTraceTransfer(this.InstanceId
))
385 WorkflowExecutor executor
= _runtime
.Load(this);
386 if (executor
.IsInstanceValid
)
390 executor
.ApplyWorkflowChanges(workflowChanges
);
393 catch (InvalidOperationException
)
395 if (executor
.IsInstanceValid
)
403 public void EnqueueItem(IComparable queueName
, Object item
, IPendingWork pendingWork
, Object workItem
)
405 using (new WorkflowTraceTransfer(this.InstanceId
))
409 WorkflowExecutor executor
= _runtime
.Load(this);
412 executor
.EnqueueItem(queueName
, item
, pendingWork
, workItem
);
415 catch (InvalidOperationException
)
417 if (executor
.IsInstanceValid
)
424 public void EnqueueItemOnIdle(IComparable queueName
, Object item
, IPendingWork pendingWork
, Object workItem
)
426 using (new WorkflowTraceTransfer(this.InstanceId
))
430 WorkflowExecutor executor
= _runtime
.Load(this);
431 if (executor
.IsInstanceValid
)
435 executor
.EnqueueItemOnIdle(queueName
, item
, pendingWork
, workItem
);
438 catch (InvalidOperationException
)
440 if (executor
.IsInstanceValid
)
448 internal WorkflowExecutor
GetWorkflowResourceUNSAFE()
452 WorkflowExecutor executor
= _runtime
.Load(this);
453 if (executor
.IsInstanceValid
)
459 catch (InvalidOperationException
)
461 if (executor
.IsInstanceValid
)
468 public override bool Equals(Object obj
)
470 WorkflowInstance instance
= obj
as WorkflowInstance
;
471 if (instance
== null)
474 return this._instanceId
== instance
._instanceId
;
477 public override int GetHashCode()
479 return this._instanceId
.GetHashCode();
484 using (new WorkflowTraceTransfer(this.InstanceId
))
488 WorkflowExecutor executor
= _runtime
.Load(this);
489 if (executor
.IsInstanceValid
)
496 catch (InvalidOperationException
)
498 if (executor
.IsInstanceValid
)