Bump corefx
[mono-project.git] / mcs / class / referencesource / System.Workflow.Runtime / WorkflowInstance.cs
blob170ce15111a34377d367894f916ec87ac303b27f
1 // ****************************************************************************
2 // Copyright (C) Microsoft Corporation. All rights reserved.
3 //
5 using System;
6 using System.IO;
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
20 /// <summary>
21 /// Schedule Instance handed over to the client
22 /// </summary>
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
43 get
45 return _instanceId;
49 public WorkflowRuntime WorkflowRuntime
51 get
53 return _runtime;
57 internal WorkflowExecutor DeadWorkflow
59 set
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();
72 while (true)
74 WorkflowExecutor executor = _runtime.Load(this);
75 if (executor.IsInstanceValid)
77 try
79 return executor.GetWorkflowQueueInfos();
81 catch (InvalidOperationException)
83 if (executor.IsInstanceValid)
84 throw;
90 public DateTime GetWorkflowNextTimerExpiration()
92 while (true)
94 WorkflowExecutor executor = _runtime.Load(this);
95 if (executor.IsInstanceValid)
97 try
99 return executor.GetWorkflowNextTimerExpiration();
101 catch (InvalidOperationException)
103 if (executor.IsInstanceValid)
104 throw;
110 public Activity GetWorkflowDefinition()
112 while (true)
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
121 // instances.
122 return executor.GetWorkflowDefinitionClone("");
124 catch (InvalidOperationException)
126 if (executor.IsInstanceValid)
127 throw;
133 public void Load()
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)
157 throw;
161 return false;
165 public void Suspend(string error)
167 using (new WorkflowTraceTransfer(this.InstanceId))
169 while (true)
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);
179 return;
181 catch (InvalidOperationException)
183 if (executor.IsInstanceValid)
184 throw;
186 catch (ExecutorLocksHeldException e)
190 e.Handle.WaitOne();
192 catch (ObjectDisposedException)
194 // If an ObjectDisposedException is thrown because
195 // the WaitHandle has already closed, nothing to worry
196 // about. Move on.
204 public void Unload()
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));
210 while (true)
212 WorkflowExecutor executor = _runtime.Load(this);
213 if (executor.IsInstanceValid)
217 executor.Unload();
218 return;
220 catch (InvalidOperationException)
222 if (executor.IsInstanceValid)
223 throw;
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
235 // about. Move on.
243 public void Resume()
245 using (new WorkflowTraceTransfer(this.InstanceId))
247 while (true)
249 WorkflowExecutor executor = _runtime.Load(this);
250 if (executor.IsInstanceValid)
254 executor.Resume();
255 break;
257 catch (InvalidOperationException)
259 if (executor.IsInstanceValid)
260 throw;
267 internal void ProcessTimers(object ignored)
269 ProcessTimers();
272 internal void ProcessTimers()
274 using (new WorkflowTraceTransfer(this.InstanceId))
276 while (true)
278 WorkflowExecutor executor = null;
281 executor = _runtime.Load(this);
283 catch (InvalidOperationException)
285 break;
287 if (executor != null && executor.IsInstanceValid)
291 executor.DeliverTimerSubscriptions();
292 break;
294 catch (InvalidOperationException)
296 if (executor.IsInstanceValid)
297 throw;
304 public void Terminate(string error)
306 using (new WorkflowTraceTransfer(this.InstanceId))
308 while (true)
310 WorkflowExecutor executor = _runtime.Load(this);
311 if (executor.IsInstanceValid)
315 executor.Terminate(error);
316 break;
318 catch (InvalidOperationException)
320 if (executor.IsInstanceValid)
321 throw;
328 public void Abort()
330 using (new WorkflowTraceTransfer(this.InstanceId))
332 while (true)
334 WorkflowExecutor executor = _runtime.Load(this);
335 if (executor.IsInstanceValid)
337 if (executor.WorkflowStatus == WorkflowStatus.Created)
338 throw new InvalidOperationException(ExecutionStringManager.CannotAbortBeforeStart);
342 executor.Abort();
343 break;
345 catch (InvalidOperationException)
347 if (executor.IsInstanceValid)
348 throw;
355 public void ReloadTrackingProfiles()
357 using (new WorkflowTraceTransfer(this.InstanceId))
359 while (true)
361 WorkflowExecutor executor = _runtime.Load(this);
362 if (executor.IsInstanceValid)
366 _runtime.TrackingListenerFactory.ReloadProfiles(executor);
367 break;
369 catch (InvalidOperationException)
371 if (executor.IsInstanceValid)
372 throw;
379 public void ApplyWorkflowChanges(WorkflowChanges workflowChanges)
381 using (new WorkflowTraceTransfer(this.InstanceId))
383 while (true)
385 WorkflowExecutor executor = _runtime.Load(this);
386 if (executor.IsInstanceValid)
390 executor.ApplyWorkflowChanges(workflowChanges);
391 break;
393 catch (InvalidOperationException)
395 if (executor.IsInstanceValid)
396 throw;
403 public void EnqueueItem(IComparable queueName, Object item, IPendingWork pendingWork, Object workItem)
405 using (new WorkflowTraceTransfer(this.InstanceId))
407 while (true)
409 WorkflowExecutor executor = _runtime.Load(this);
412 executor.EnqueueItem(queueName, item, pendingWork, workItem);
413 break;
415 catch (InvalidOperationException)
417 if (executor.IsInstanceValid)
418 throw;
424 public void EnqueueItemOnIdle(IComparable queueName, Object item, IPendingWork pendingWork, Object workItem)
426 using (new WorkflowTraceTransfer(this.InstanceId))
428 while (true)
430 WorkflowExecutor executor = _runtime.Load(this);
431 if (executor.IsInstanceValid)
435 executor.EnqueueItemOnIdle(queueName, item, pendingWork, workItem);
436 break;
438 catch (InvalidOperationException)
440 if (executor.IsInstanceValid)
441 throw;
448 internal WorkflowExecutor GetWorkflowResourceUNSAFE()
450 while (true)
452 WorkflowExecutor executor = _runtime.Load(this);
453 if (executor.IsInstanceValid)
457 return executor;
459 catch (InvalidOperationException)
461 if (executor.IsInstanceValid)
462 throw;
468 public override bool Equals(Object obj)
470 WorkflowInstance instance = obj as WorkflowInstance;
471 if (instance == null)
472 return false;
474 return this._instanceId == instance._instanceId;
477 public override int GetHashCode()
479 return this._instanceId.GetHashCode();
482 public void Start()
484 using (new WorkflowTraceTransfer(this.InstanceId))
486 while (true)
488 WorkflowExecutor executor = _runtime.Load(this);
489 if (executor.IsInstanceValid)
493 executor.Start();
494 break;
496 catch (InvalidOperationException)
498 if (executor.IsInstanceValid)
499 throw;