e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
145 lines
4.8 KiB
C#
145 lines
4.8 KiB
C#
//-----------------------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace System.Activities
|
|
{
|
|
using System;
|
|
using System.Activities.DynamicUpdate;
|
|
using System.Activities.Hosting;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Runtime;
|
|
using System.Runtime.DurableInstancing;
|
|
using System.Threading;
|
|
using System.Xml.Linq;
|
|
|
|
// Wrapper over instance data retrieved from the Instance Store but not yet loaded into a WorkflowApplication.
|
|
// Once this instance is loaded into a WFApp using WFApp.Load(), this object is stale and trying to abort or reload it wil throw.
|
|
// Free-threaded: needs to be resillient to simultaneous loads/aborts on multiple threads
|
|
public class WorkflowApplicationInstance
|
|
{
|
|
private int state;
|
|
|
|
internal WorkflowApplicationInstance(
|
|
WorkflowApplication.PersistenceManagerBase persistenceManager,
|
|
IDictionary<XName, InstanceValue> values,
|
|
WorkflowIdentity definitionIdentity)
|
|
{
|
|
this.PersistenceManager = persistenceManager;
|
|
this.Values = values;
|
|
this.DefinitionIdentity = definitionIdentity;
|
|
this.state = (int)State.Initialized;
|
|
}
|
|
|
|
private enum State
|
|
{
|
|
Initialized,
|
|
Loaded,
|
|
Aborted
|
|
}
|
|
|
|
public WorkflowIdentity DefinitionIdentity
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public InstanceStore InstanceStore
|
|
{
|
|
get
|
|
{
|
|
return this.PersistenceManager.InstanceStore;
|
|
}
|
|
}
|
|
|
|
public Guid InstanceId
|
|
{
|
|
get
|
|
{
|
|
return this.PersistenceManager.InstanceId;
|
|
}
|
|
}
|
|
|
|
internal WorkflowApplication.PersistenceManagerBase PersistenceManager
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
internal IDictionary<XName, InstanceValue> Values
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public void Abandon()
|
|
{
|
|
this.Abandon(ActivityDefaults.DeleteTimeout);
|
|
}
|
|
|
|
public void Abandon(TimeSpan timeout)
|
|
{
|
|
TimeoutHelper.ThrowIfNegativeArgument(timeout);
|
|
|
|
this.MarkAsAbandoned();
|
|
WorkflowApplication.DiscardInstance(this.PersistenceManager, timeout);
|
|
}
|
|
|
|
public IAsyncResult BeginAbandon(AsyncCallback callback, object state)
|
|
{
|
|
return this.BeginAbandon(ActivityDefaults.DeleteTimeout, callback, state);
|
|
}
|
|
|
|
public IAsyncResult BeginAbandon(TimeSpan timeout, AsyncCallback callback, object state)
|
|
{
|
|
TimeoutHelper.ThrowIfNegativeArgument(timeout);
|
|
|
|
this.MarkAsAbandoned();
|
|
return WorkflowApplication.BeginDiscardInstance(this.PersistenceManager, timeout, callback, state);
|
|
}
|
|
|
|
public void EndAbandon(IAsyncResult asyncResult)
|
|
{
|
|
WorkflowApplication.EndDiscardInstance(asyncResult);
|
|
}
|
|
|
|
[SuppressMessage(FxCop.Category.Design, FxCop.Rule.AvoidOutParameters, Justification = "Approved Design. Returning a bool makes the intent much clearer than something that just returns a list.")]
|
|
public bool CanApplyUpdate(DynamicUpdateMap updateMap, out IList<ActivityBlockingUpdate> activitiesBlockingUpdate)
|
|
{
|
|
if (updateMap == null)
|
|
{
|
|
throw FxTrace.Exception.ArgumentNull("updateMap");
|
|
}
|
|
|
|
activitiesBlockingUpdate = WorkflowApplication.GetActivitiesBlockingUpdate(this, updateMap);
|
|
return activitiesBlockingUpdate == null || activitiesBlockingUpdate.Count == 0;
|
|
}
|
|
|
|
internal void MarkAsLoaded()
|
|
{
|
|
int oldState = Interlocked.CompareExchange(ref this.state, (int)State.Loaded, (int)State.Initialized);
|
|
this.ThrowIfLoadedOrAbandoned((State)oldState);
|
|
}
|
|
|
|
private void MarkAsAbandoned()
|
|
{
|
|
int oldState = Interlocked.CompareExchange(ref this.state, (int)State.Aborted, (int)State.Initialized);
|
|
this.ThrowIfLoadedOrAbandoned((State)oldState);
|
|
}
|
|
|
|
private void ThrowIfLoadedOrAbandoned(State oldState)
|
|
{
|
|
if (oldState == State.Loaded)
|
|
{
|
|
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.WorkflowApplicationInstanceLoaded));
|
|
}
|
|
|
|
if (oldState == State.Aborted)
|
|
{
|
|
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.WorkflowApplicationInstanceAbandoned));
|
|
}
|
|
}
|
|
}
|
|
}
|