Imported Upstream version 4.6.0.125

Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-08-03 10:59:49 +00:00
parent a569aebcfd
commit e79aa3c0ed
17047 changed files with 3137615 additions and 392334 deletions

View File

@@ -0,0 +1,63 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Markup;
using System.Diagnostics.CodeAnalysis;
using System.Runtime;
using System.Collections.ObjectModel;
[SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldNotHaveIncorrectSuffix, Justification = "Optimizing for XAML naming.")]
[ContentProperty("Collection")]
public sealed class AddToCollection<T> : CodeActivity
{
[RequiredArgument]
[DefaultValue(null)]
public InArgument<ICollection<T>> Collection
{
get;
set;
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument<T> Item
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
Collection<RuntimeArgument> arguments = new Collection<RuntimeArgument>();
RuntimeArgument collectionArgument = new RuntimeArgument("Collection", typeof(ICollection<T>), ArgumentDirection.In, true);
metadata.Bind(this.Collection, collectionArgument);
arguments.Add(collectionArgument);
RuntimeArgument itemArgument = new RuntimeArgument("Item", typeof(T), ArgumentDirection.In, true);
metadata.Bind(this.Item, itemArgument);
arguments.Add(itemArgument);
metadata.SetArgumentsCollection(arguments);
}
protected override void Execute(CodeActivityContext context)
{
ICollection<T> collection = this.Collection.Get(context);
if (collection == null)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CollectionActivityRequiresCollection(this.DisplayName)));
}
T item = this.Item.Get(context);
collection.Add(item);
}
}
}

View File

@@ -0,0 +1,126 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Statements
{
using System.Activities;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime;
public sealed class Assign : CodeActivity
{
public Assign()
: base()
{
}
[RequiredArgument]
[DefaultValue(null)]
public OutArgument To
{
get;
set;
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument Value
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
Collection<RuntimeArgument> arguments = new Collection<RuntimeArgument>();
Type valueType = TypeHelper.ObjectType;
if (this.Value != null)
{
valueType = this.Value.ArgumentType;
}
RuntimeArgument valueArgument = new RuntimeArgument("Value", valueType, ArgumentDirection.In, true);
metadata.Bind(this.Value, valueArgument);
Type toType = TypeHelper.ObjectType;
if (this.To != null)
{
toType = this.To.ArgumentType;
}
RuntimeArgument toArgument = new RuntimeArgument("To", toType, ArgumentDirection.Out, true);
metadata.Bind(this.To, toArgument);
arguments.Add(valueArgument);
arguments.Add(toArgument);
metadata.SetArgumentsCollection(arguments);
if (this.Value != null && this.To != null)
{
if (!TypeHelper.AreTypesCompatible(this.Value.ArgumentType, this.To.ArgumentType))
{
metadata.AddValidationError(SR.TypeMismatchForAssign(
this.Value.ArgumentType,
this.To.ArgumentType,
this.DisplayName));
}
}
}
protected override void Execute(CodeActivityContext context)
{
this.To.Set(context, this.Value.Get(context));
}
}
public sealed class Assign<T> : CodeActivity
{
public Assign()
: base()
{
}
[RequiredArgument]
[DefaultValue(null)]
public OutArgument<T> To
{
get;
set;
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument<T> Value
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
Collection<RuntimeArgument> arguments = new Collection<RuntimeArgument>();
RuntimeArgument valueArgument = new RuntimeArgument("Value", typeof(T), ArgumentDirection.In, true);
metadata.Bind(this.Value, valueArgument);
RuntimeArgument toArgument = new RuntimeArgument("To", typeof(T), ArgumentDirection.Out, true);
metadata.Bind(this.To, toArgument);
arguments.Add(valueArgument);
arguments.Add(toArgument);
metadata.SetArgumentsCollection(arguments);
}
protected override void Execute(CodeActivityContext context)
{
context.SetValue(this.To, this.Value.Get(context));
}
}
}

View File

@@ -0,0 +1,43 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime;
[DataContract]
class BookmarkTable
{
//Number of bookmarks used internally
static int tableSize = Enum.GetValues(typeof(CompensationBookmarkName)).Length;
Bookmark[] bookmarkTable;
public BookmarkTable()
{
this.bookmarkTable = new Bookmark[tableSize];
}
public Bookmark this[CompensationBookmarkName bookmarkName]
{
get
{
return this.bookmarkTable[(int)bookmarkName];
}
set
{
this.bookmarkTable[(int)bookmarkName] = value;
}
}
[DataMember(Name = "bookmarkTable")]
internal Bookmark[] SerializedBookmarkTable
{
get { return this.bookmarkTable; }
set { this.bookmarkTable = value; }
}
}
}

View File

@@ -0,0 +1,120 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Activities;
using System.Activities.DynamicUpdate;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.Collections;
using System.Windows.Markup;
[ContentProperty("Body")]
public sealed class CancellationScope : NativeActivity
{
Collection<Variable> variables;
Variable<bool> suppressCancel;
public CancellationScope()
: base()
{
this.suppressCancel = new Variable<bool>();
}
public Collection<Variable> Variables
{
get
{
if (this.variables == null)
{
this.variables = new ValidatingCollection<Variable>
{
// disallow null values
OnAddValidationCallback = item =>
{
if (item == null)
{
throw FxTrace.Exception.ArgumentNull("item");
}
}
};
}
return this.variables;
}
}
[DefaultValue(null)]
[DependsOn("Variables")]
public Activity Body
{
get;
set;
}
[DefaultValue(null)]
[DependsOn("Body")]
public Activity CancellationHandler
{
get;
set;
}
protected override void OnCreateDynamicUpdateMap(NativeActivityUpdateMapMetadata metadata, Activity originalActivity)
{
metadata.AllowUpdateInsideThisActivity();
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.AddChild(this.Body);
metadata.AddChild(this.CancellationHandler);
metadata.SetVariablesCollection(this.Variables);
metadata.AddImplementationVariable(this.suppressCancel);
}
protected override void Execute(NativeActivityContext context)
{
if (this.Body != null)
{
context.ScheduleActivity(this.Body, new CompletionCallback(OnBodyComplete));
}
}
void OnBodyComplete(NativeActivityContext context, ActivityInstance completedInstance)
{
// Determine whether to run the Cancel based on whether the body
// canceled rather than whether cancel had been requested.
if (completedInstance.State == ActivityInstanceState.Canceled ||
(context.IsCancellationRequested && completedInstance.State == ActivityInstanceState.Faulted))
{
// We don't cancel the cancel handler
this.suppressCancel.Set(context, true);
context.MarkCanceled();
if (this.CancellationHandler != null)
{
context.ScheduleActivity(this.CancellationHandler, onFaulted: new FaultCallback(OnExceptionFromCancelHandler));
}
}
}
protected override void Cancel(NativeActivityContext context)
{
bool suppressCancel = this.suppressCancel.Get(context);
if (!suppressCancel)
{
context.CancelChildren();
}
}
void OnExceptionFromCancelHandler(NativeActivityFaultContext context, Exception propagatedException, ActivityInstance propagatedFrom)
{
this.suppressCancel.Set(context, false);
}
}
}

View File

@@ -0,0 +1,68 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Activities;
using System.Activities.Runtime;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime;
using System.Windows.Markup;
[SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldNotMatchKeywords, Justification = "Optimizing for XAML naming. VB imperative users will [] qualify (e.g. New [Catch](Of Exception))")]
public abstract class Catch
{
internal Catch()
{
}
public abstract Type ExceptionType
{
get;
}
internal abstract ActivityDelegate GetAction();
internal abstract void ScheduleAction(NativeActivityContext context, Exception exception, CompletionCallback completionCallback, FaultCallback faultCallback);
}
[ContentProperty("Action")]
[SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldNotMatchKeywords, Justification = "Optimizing for XAML naming. VB imperative users will [] qualify (e.g. New [Catch](Of Exception))")]
public sealed class Catch<TException> : Catch
where TException : Exception
{
public Catch()
: base()
{
}
public override Type ExceptionType
{
get
{
return typeof(TException);
}
}
[DefaultValue(null)]
public ActivityAction<TException> Action
{
get;
set;
}
internal override ActivityDelegate GetAction()
{
return this.Action;
}
internal override void ScheduleAction(NativeActivityContext context, Exception exception,
CompletionCallback completionCallback, FaultCallback faultCallback)
{
context.ScheduleAction(this.Action, (TException)exception, completionCallback, faultCallback);
}
}
}

View File

@@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Markup;
using System.Diagnostics.CodeAnalysis;
using System.Runtime;
using System.Collections.ObjectModel;
[SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldNotHaveIncorrectSuffix, Justification = "Optimizing for XAML naming.")]
[ContentProperty("Collection")]
public sealed class ClearCollection<T> : CodeActivity
{
[RequiredArgument]
[DefaultValue(null)]
public InArgument<ICollection<T>> Collection
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
RuntimeArgument collectionArgument = new RuntimeArgument("Collection", typeof(ICollection<T>), ArgumentDirection.In, true);
metadata.Bind(this.Collection, collectionArgument);
metadata.SetArgumentsCollection(new Collection<RuntimeArgument> { collectionArgument });
}
protected override void Execute(CodeActivityContext context)
{
ICollection<T> collection = this.Collection.Get(context);
if (collection == null)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CollectionActivityRequiresCollection(this.DisplayName)));
}
collection.Clear();
}
}
}

View File

@@ -0,0 +1,231 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime;
using System.Activities.Validation;
using System.Linq;
using System.Activities.Expressions;
public sealed class Compensate : NativeActivity
{
static Constraint compensateWithNoTarget = Compensate.CompensateWithNoTarget();
InternalCompensate internalCompensate;
DefaultCompensation defaultCompensation;
Variable<CompensationToken> currentCompensationToken;
public Compensate()
: base()
{
this.currentCompensationToken = new Variable<CompensationToken>();
}
[DefaultValue(null)]
public InArgument<CompensationToken> Target
{
get;
set;
}
DefaultCompensation DefaultCompensation
{
get
{
if (this.defaultCompensation == null)
{
this.defaultCompensation = new DefaultCompensation()
{
Target = new InArgument<CompensationToken>(this.currentCompensationToken),
};
}
return this.defaultCompensation;
}
}
InternalCompensate InternalCompensate
{
get
{
if (this.internalCompensate == null)
{
this.internalCompensate = new InternalCompensate()
{
Target = new InArgument<CompensationToken>(new ArgumentValue<CompensationToken> { ArgumentName = "Target" }),
};
}
return this.internalCompensate;
}
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
RuntimeArgument targetArgument = new RuntimeArgument("Target", typeof(CompensationToken), ArgumentDirection.In);
metadata.Bind(this.Target, targetArgument);
metadata.SetArgumentsCollection(new Collection<RuntimeArgument> { targetArgument });
metadata.SetImplementationVariablesCollection(new Collection<Variable> { this.currentCompensationToken });
Fx.Assert(DefaultCompensation != null, "DefaultCompensation must be valid");
Fx.Assert(InternalCompensate != null, "InternalCompensate must be valid");
metadata.SetImplementationChildrenCollection(
new Collection<Activity>
{
DefaultCompensation,
InternalCompensate
});
}
internal override IList<Constraint> InternalGetConstraints()
{
return new List<Constraint>(1) { compensateWithNoTarget };
}
static Constraint CompensateWithNoTarget()
{
DelegateInArgument<Compensate> element = new DelegateInArgument<Compensate> { Name = "element" };
DelegateInArgument<ValidationContext> validationContext = new DelegateInArgument<ValidationContext> { Name = "validationContext" };
Variable<bool> assertFlag = new Variable<bool> { Name = "assertFlag" };
Variable<IEnumerable<Activity>> elements = new Variable<IEnumerable<Activity>>() { Name = "elements" };
Variable<int> index = new Variable<int>() { Name = "index" };
return new Constraint<Compensate>
{
Body = new ActivityAction<Compensate, ValidationContext>
{
Argument1 = element,
Argument2 = validationContext,
Handler = new Sequence
{
Variables =
{
assertFlag,
elements,
index
},
Activities =
{
new If
{
Condition = new InArgument<bool>((env) => element.Get(env).Target != null),
Then = new Assign<bool>
{
To = assertFlag,
Value = true
},
Else = new Sequence
{
Activities =
{
new Assign<IEnumerable<Activity>>
{
To = elements,
Value = new GetParentChain
{
ValidationContext = validationContext,
},
},
new While(env => (assertFlag.Get(env) != true) && index.Get(env) < elements.Get(env).Count())
{
Body = new Sequence
{
Activities =
{
new If(env => (elements.Get(env).ElementAt(index.Get(env))).GetType() == typeof(CompensationParticipant))
{
Then = new Assign<bool>
{
To = assertFlag,
Value = true
},
},
new Assign<int>
{
To = index,
Value = new InArgument<int>(env => index.Get(env) + 1)
},
}
}
}
}
}
},
new AssertValidation
{
Assertion = new InArgument<bool>(assertFlag),
Message = new InArgument<string>(SR.CompensateWithNoTargetConstraint)
}
}
}
}
};
}
protected override void Execute(NativeActivityContext context)
{
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
if (compensationExtension == null)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CompensateWithoutCompensableActivity(this.DisplayName)));
}
if (Target.IsEmpty)
{
CompensationToken ambientCompensationToken = (CompensationToken)context.Properties.Find(CompensationToken.PropertyName);
CompensationTokenData ambientTokenData = ambientCompensationToken == null ? null : compensationExtension.Get(ambientCompensationToken.CompensationId);
if (ambientTokenData != null && ambientTokenData.IsTokenValidInSecondaryRoot)
{
this.currentCompensationToken.Set(context, ambientCompensationToken);
if (ambientTokenData.ExecutionTracker.Count > 0)
{
context.ScheduleActivity(DefaultCompensation);
}
}
else
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.InvalidCompensateActivityUsage(this.DisplayName)));
}
}
else
{
CompensationToken compensationToken = Target.Get(context);
CompensationTokenData tokenData = compensationToken == null ? null : compensationExtension.Get(compensationToken.CompensationId);
if (compensationToken == null)
{
throw FxTrace.Exception.Argument("Target", SR.InvalidCompensationToken(this.DisplayName));
}
if (compensationToken.CompensateCalled)
{
// No-Op
return;
}
if (tokenData == null || tokenData.CompensationState != CompensationState.Completed)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CompensableActivityAlreadyConfirmedOrCompensated));
}
// A valid in-arg was passed...
tokenData.CompensationState = CompensationState.Compensating;
compensationToken.CompensateCalled = true;
context.ScheduleActivity(InternalCompensate);
}
}
protected override void Cancel(NativeActivityContext context)
{
// Suppress Cancel
}
}
}

View File

@@ -0,0 +1,13 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
static class CompensationActivityStrings
{
public const string WorkflowImplicitCompensationBehavior = "Activities.Compensation.WorkflowImplicitCompensationBehavior";
}
}

View File

@@ -0,0 +1,18 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
enum CompensationBookmarkName
{
Confirmed = 0,
Canceled = 1,
Compensated = 2,
OnConfirmation = 3,
OnCompensation = 4,
OnCancellation = 5,
OnSecondaryRootScheduled = 6,
}
}

View File

@@ -0,0 +1,190 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Activities.Hosting;
using System.Activities.Persistence;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime;
using System.Xml.Linq;
public class CompensationExtension : PersistenceParticipant, IWorkflowInstanceExtension
{
static readonly XNamespace compensationNamespace = XNamespace.Get("urn:schemas-microsoft-com:System.Activities/4.0/compensation");
static readonly XName compensationExtensionData = compensationNamespace.GetName("Data");
[Fx.Tag.SynchronizationObject(Blocking = false)]
Dictionary<long, CompensationTokenData> compensationTokenTable;
public CompensationExtension()
{
this.compensationTokenTable = new Dictionary<long, CompensationTokenData>();
}
internal Dictionary<long, CompensationTokenData> CompensationTokenTable
{
get
{
return this.compensationTokenTable;
}
private set
{
this.compensationTokenTable = value;
}
}
internal long Id
{
get;
set;
}
internal Bookmark WorkflowCompensation
{
get;
set;
}
internal Bookmark WorkflowConfirmation
{
get;
set;
}
internal Bookmark WorkflowCompensationScheduled
{
get;
private set;
}
internal bool IsWorkflowCompensationBehaviorScheduled
{
get;
private set;
}
internal WorkflowInstanceProxy Instance
{
get;
private set;
}
internal void Add(long compensationId, CompensationTokenData compensationToken)
{
Fx.Assert(compensationToken != null, "compensationToken must be valid");
this.CompensationTokenTable[compensationId] = compensationToken;
}
internal void Remove(long compensationId)
{
this.CompensationTokenTable.Remove(compensationId);
}
internal CompensationTokenData Get(long compensationId)
{
CompensationTokenData compensationToken = null;
this.CompensationTokenTable.TryGetValue(compensationId, out compensationToken);
return compensationToken;
}
internal Bookmark FindBookmark(long compensationId, CompensationBookmarkName bookmarkName)
{
CompensationTokenData compensationToken = null;
Bookmark bookmark = null;
if (this.CompensationTokenTable.TryGetValue(compensationId, out compensationToken))
{
bookmark = compensationToken.BookmarkTable[bookmarkName];
}
return bookmark;
}
internal void SetupWorkflowCompensationBehavior(NativeActivityContext context, BookmarkCallback callback, Activity workflowCompensationBehavior)
{
this.WorkflowCompensationScheduled = context.CreateBookmark(callback);
Fx.Assert(workflowCompensationBehavior != null, "WorkflowCompensationBehavior must be valid");
context.ScheduleSecondaryRoot(workflowCompensationBehavior, null);
// Add the root compensationToken to track all root CA execution order.
this.Add(CompensationToken.RootCompensationId, new CompensationTokenData(CompensationToken.RootCompensationId, CompensationToken.RootCompensationId));
this.IsWorkflowCompensationBehaviorScheduled = true;
}
internal long GetNextId()
{
return ++this.Id;
}
internal void NotifyMessage(NativeActivityContext context, long compensationId, CompensationBookmarkName compensationBookmark)
{
Bookmark bookmark = FindBookmark(compensationId, compensationBookmark);
if (bookmark != null)
{
context.ResumeBookmark(bookmark, compensationId);
}
else
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarkNotRegistered(compensationBookmark)));
}
}
[SuppressMessage(FxCop.Category.Design, FxCop.Rule.InterfaceMethodsShouldBeCallableByChildTypes,
Justification = "The inherit class don't need to call this method or access this method")]
IEnumerable<object> IWorkflowInstanceExtension.GetAdditionalExtensions()
{
return null;
}
[SuppressMessage(FxCop.Category.Design, FxCop.Rule.InterfaceMethodsShouldBeCallableByChildTypes,
Justification = "The inherit class don't need to call this method or access this method")]
void IWorkflowInstanceExtension.SetInstance(WorkflowInstanceProxy instance)
{
this.Instance = instance;
}
// PersistenceParticipant
protected override void CollectValues(out IDictionary<XName, object> readWriteValues, out IDictionary<XName, object> writeOnlyValues)
{
writeOnlyValues = null;
readWriteValues = new Dictionary<XName, object>(1)
{
{
compensationExtensionData,
new List<object>(6)
{
this.CompensationTokenTable,
this.WorkflowCompensation,
this.WorkflowConfirmation,
this.WorkflowCompensationScheduled,
this.IsWorkflowCompensationBehaviorScheduled,
this.Id
}
}
};
}
protected override void PublishValues(IDictionary<XName, object> readWriteValues)
{
object data;
if (readWriteValues.TryGetValue(compensationExtensionData, out data))
{
List<object> list = (List<object>)data;
this.CompensationTokenTable = (Dictionary<long, CompensationTokenData>)list[0];
this.WorkflowCompensation = (Bookmark)list[1];
this.WorkflowConfirmation = (Bookmark)list[2];
this.WorkflowCompensationScheduled = (Bookmark)list[3];
this.IsWorkflowCompensationBehaviorScheduled = (bool)list[4];
this.Id = (long)list[5];
}
}
}
}

View File

@@ -0,0 +1,424 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Activities.DynamicUpdate;
using System.Collections.Generic;
using System.Runtime;
using System.Collections.ObjectModel;
sealed class CompensationParticipant : NativeActivity
{
InArgument<long> compensationId;
Variable<CompensationToken> currentCompensationToken;
public CompensationParticipant(Variable<long> compensationId)
: base()
{
this.compensationId = compensationId;
this.currentCompensationToken = new Variable<CompensationToken>();
DefaultCompensation = new DefaultCompensation()
{
Target = new InArgument<CompensationToken>(this.currentCompensationToken),
};
DefaultConfirmation = new DefaultConfirmation()
{
Target = new InArgument<CompensationToken>(this.currentCompensationToken),
};
}
public Activity CompensationHandler
{
get;
set;
}
public Activity ConfirmationHandler
{
get;
set;
}
public Activity CancellationHandler
{
get;
set;
}
Activity DefaultCompensation
{
get;
set;
}
Activity DefaultConfirmation
{
get;
set;
}
protected override bool CanInduceIdle
{
get
{
return true;
}
}
protected override void OnCreateDynamicUpdateMap(NativeActivityUpdateMapMetadata metadata, Activity originalActivity)
{
metadata.AllowUpdateInsideThisActivity();
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.SetImplementationVariablesCollection(
new Collection<Variable>
{
this.currentCompensationToken,
});
Collection<Activity> children = new Collection<Activity>();
if (this.CompensationHandler != null)
{
children.Add(CompensationHandler);
}
if (this.ConfirmationHandler != null)
{
children.Add(ConfirmationHandler);
}
if (this.CancellationHandler != null)
{
children.Add(CancellationHandler);
}
metadata.SetChildrenCollection(children);
Collection<Activity> implementationChildren = new Collection<Activity>();
Fx.Assert(DefaultCompensation != null, "DefaultCompensation must be valid");
implementationChildren.Add(DefaultCompensation);
Fx.Assert(DefaultConfirmation != null, "DefaultConfirmation must be valid");
implementationChildren.Add(DefaultConfirmation);
metadata.SetImplementationChildrenCollection(implementationChildren);
RuntimeArgument compensationIdArgument = new RuntimeArgument("CompensationId", typeof(long), ArgumentDirection.In);
metadata.Bind(this.compensationId, compensationIdArgument);
metadata.AddArgument(compensationIdArgument);
}
protected override void Execute(NativeActivityContext context)
{
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
long compensationId = this.compensationId.Get(context);
Fx.Assert(compensationId != CompensationToken.RootCompensationId, "CompensationId passed to the SecondaryRoot must be valid");
CompensationTokenData compensationToken = compensationExtension.Get(compensationId);
Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
CompensationToken token = new CompensationToken(compensationToken);
this.currentCompensationToken.Set(context, token);
compensationToken.IsTokenValidInSecondaryRoot = true;
context.Properties.Add(CompensationToken.PropertyName, token);
Fx.Assert(compensationToken.BookmarkTable[CompensationBookmarkName.OnConfirmation] == null, "Bookmark should not be already initialized in the bookmark table.");
compensationToken.BookmarkTable[CompensationBookmarkName.OnConfirmation] = context.CreateBookmark(new BookmarkCallback(OnConfirmation));
Fx.Assert(compensationToken.BookmarkTable[CompensationBookmarkName.OnCompensation] == null, "Bookmark should not be already initialized in the bookmark table.");
compensationToken.BookmarkTable[CompensationBookmarkName.OnCompensation] = context.CreateBookmark(new BookmarkCallback(OnCompensation));
Fx.Assert(compensationToken.BookmarkTable[CompensationBookmarkName.OnCancellation] == null, "Bookmark should not be already initialized in the bookmark table.");
compensationToken.BookmarkTable[CompensationBookmarkName.OnCancellation] = context.CreateBookmark(new BookmarkCallback(OnCancellation));
Bookmark onSecondaryRootScheduled = compensationToken.BookmarkTable[CompensationBookmarkName.OnSecondaryRootScheduled];
Fx.Assert(onSecondaryRootScheduled != null, "onSecondaryRootScheduled bookmark must be already registered.");
compensationToken.BookmarkTable[CompensationBookmarkName.OnSecondaryRootScheduled] = null;
context.ResumeBookmark(onSecondaryRootScheduled, compensationId);
}
void OnConfirmation(NativeActivityContext context, Bookmark bookmark, object value)
{
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
long compensationId = (long)value;
Fx.Assert(compensationId != CompensationToken.RootCompensationId, "CompensationId must be passed when resuming the Completed bookmark");
CompensationTokenData compensationToken = compensationExtension.Get(compensationId);
Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
Fx.Assert(compensationToken.CompensationState == CompensationState.Confirming, "CompensationState should be in Confirming state");
if (TD.CompensationStateIsEnabled())
{
TD.CompensationState(compensationToken.DisplayName, compensationToken.CompensationState.ToString());
}
compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnCancellation);
compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnCompensation);
if (ConfirmationHandler != null)
{
context.ScheduleActivity(ConfirmationHandler, new CompletionCallback(OnConfirmationHandlerComplete), new FaultCallback(OnExceptionFromHandler));
}
else
{
this.currentCompensationToken.Set(context, new CompensationToken(compensationToken));
if (compensationToken.ExecutionTracker.Count > 0)
{
context.ScheduleActivity(DefaultConfirmation, new CompletionCallback(this.OnConfirmationComplete));
}
else
{
compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.Confirmed);
}
}
}
void OnConfirmationHandlerComplete(NativeActivityContext context, ActivityInstance completedInstance)
{
Fx.Assert(context != null, "context must be valid");
Fx.Assert(completedInstance != null, "completedInstance must be valid");
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context));
Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
if (completedInstance.State == ActivityInstanceState.Closed)
{
Fx.Assert(compensationToken.CompensationState == CompensationState.Confirming, "CompensationParticipant should be in Confirming State");
this.currentCompensationToken.Set(context, new CompensationToken(compensationToken));
if (compensationToken.ExecutionTracker.Count > 0)
{
context.ScheduleActivity(DefaultConfirmation, new CompletionCallback(this.OnConfirmationComplete));
}
else
{
compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.Confirmed);
}
}
}
void OnConfirmationComplete(NativeActivityContext context, ActivityInstance completedInstance)
{
Fx.Assert(context != null, "context must be valid");
Fx.Assert(completedInstance != null, "completedInstance must be valid");
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context));
Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
if (completedInstance.State == ActivityInstanceState.Closed)
{
compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.Confirmed);
}
}
void OnCompensation(NativeActivityContext context, Bookmark bookmark, object value)
{
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
long compensationId = (long)value;
Fx.Assert(compensationId != CompensationToken.RootCompensationId, "CompensationId must be passed when resuming the Completed bookmark");
CompensationTokenData compensationToken = compensationExtension.Get(compensationId);
Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
Fx.Assert(compensationToken.CompensationState == CompensationState.Compensating, "CompensationState should be in Compensating state");
if (TD.CompensationStateIsEnabled())
{
TD.CompensationState(compensationToken.DisplayName, compensationToken.CompensationState.ToString());
}
// Cleanup Bookmarks..
compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnCancellation);
compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnConfirmation);
if (CompensationHandler != null)
{
context.ScheduleActivity(CompensationHandler, new CompletionCallback(this.OnCompensationHandlerComplete), new FaultCallback(OnExceptionFromHandler));
}
else
{
this.currentCompensationToken.Set(context, new CompensationToken(compensationToken));
if (compensationToken.ExecutionTracker.Count > 0)
{
context.ScheduleActivity(DefaultCompensation, new CompletionCallback(this.OnCompensationComplete));
}
else
{
this.InternalOnCompensationComplete(context, compensationExtension, compensationToken);
}
}
}
void OnCompensationHandlerComplete(NativeActivityContext context, ActivityInstance completedInstance)
{
Fx.Assert(context != null, "context must be valid");
Fx.Assert(completedInstance != null, "completedInstance must be valid");
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context));
Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
if (completedInstance.State == ActivityInstanceState.Closed)
{
Fx.Assert(compensationToken.CompensationState == CompensationState.Compensating, "CompensationParticipant should be in Compensating State");
this.currentCompensationToken.Set(context, new CompensationToken(compensationToken));
if (compensationToken.ExecutionTracker.Count > 0)
{
context.ScheduleActivity(DefaultConfirmation, new CompletionCallback(this.OnCompensationComplete));
}
else
{
this.InternalOnCompensationComplete(context, compensationExtension, compensationToken);
}
}
}
void OnCancellation(NativeActivityContext context, Bookmark bookmark, object value)
{
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
long compensationId = (long)value;
Fx.Assert(compensationId != CompensationToken.RootCompensationId, "CompensationId must be passed when resuming the Completed bookmark");
CompensationTokenData compensationToken = compensationExtension.Get(compensationId);
Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
Fx.Assert(compensationToken.CompensationState == CompensationState.Canceling, "CompensationState should be in Canceling state");
if (TD.CompensationStateIsEnabled())
{
TD.CompensationState(compensationToken.DisplayName, compensationToken.CompensationState.ToString());
}
// remove bookmarks.
compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnCompensation);
compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnConfirmation);
this.currentCompensationToken.Set(context, new CompensationToken(compensationToken));
if (CancellationHandler != null)
{
context.ScheduleActivity(CancellationHandler, new CompletionCallback(this.OnCancellationHandlerComplete), new FaultCallback(OnExceptionFromHandler));
}
else
{
if (compensationToken.ExecutionTracker.Count > 0)
{
context.ScheduleActivity(DefaultCompensation, new CompletionCallback(this.OnCompensationComplete));
}
else
{
this.InternalOnCompensationComplete(context, compensationExtension, compensationToken);
}
}
}
void OnCancellationHandlerComplete(NativeActivityContext context, ActivityInstance completedInstance)
{
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context));
Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
if (completedInstance.State == ActivityInstanceState.Closed)
{
Fx.Assert(compensationToken.CompensationState == CompensationState.Canceling, "CompensationParticipant should be in Canceling State");
this.currentCompensationToken.Set(context, new CompensationToken(compensationToken));
if (compensationToken.ExecutionTracker.Count > 0)
{
context.ScheduleActivity(DefaultConfirmation, new CompletionCallback(this.OnCompensationComplete));
}
else
{
this.InternalOnCompensationComplete(context, compensationExtension, compensationToken);
}
}
}
void OnCompensationComplete(NativeActivityContext context, ActivityInstance completedInstance)
{
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context));
Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
InternalOnCompensationComplete(context, compensationExtension, compensationToken);
}
void InternalOnCompensationComplete(NativeActivityContext context, CompensationExtension compensationExtension, CompensationTokenData compensationToken)
{
switch (compensationToken.CompensationState)
{
case CompensationState.Canceling:
compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.Canceled);
break;
case CompensationState.Compensating:
compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.Compensated);
break;
default:
Fx.Assert(false, "CompensationState is in unexpected state!");
break;
}
}
void OnExceptionFromHandler(NativeActivityFaultContext context, Exception propagatedException, ActivityInstance propagatedFrom)
{
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context));
Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
InvalidOperationException exception = null;
switch (compensationToken.CompensationState)
{
case CompensationState.Confirming:
exception = new InvalidOperationException(SR.ConfirmationHandlerFatalException(compensationToken.DisplayName), propagatedException);
break;
case CompensationState.Compensating:
exception = new InvalidOperationException(SR.CompensationHandlerFatalException(compensationToken.DisplayName), propagatedException);
break;
case CompensationState.Canceling:
exception = new InvalidOperationException(SR.CancellationHandlerFatalException(compensationToken.DisplayName), propagatedException);
break;
default:
Fx.Assert(false, "CompensationState is in unexpected state!");
break;
}
context.Abort(exception);
}
}
}

View File

@@ -0,0 +1,39 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Runtime.Serialization;
[DataContract]
enum CompensationState
{
[EnumMember]
Creating,
[EnumMember]
Active,
[EnumMember]
Completed,
[EnumMember]
Confirming,
[EnumMember]
Confirmed,
[EnumMember]
Compensating,
[EnumMember]
Compensated,
[EnumMember]
Canceling,
[EnumMember]
Canceled,
}
}

View File

@@ -0,0 +1,46 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime;
using System.Diagnostics.CodeAnalysis;
using System.ComponentModel;
[Fx.Tag.XamlVisible(false)]
[DataContract]
public sealed class CompensationToken
{
internal const string PropertyName = "System.Compensation.CompensationToken";
internal const long RootCompensationId = 0;
internal CompensationToken(CompensationTokenData tokenData)
{
this.CompensationId = tokenData.CompensationId;
}
[DataMember(EmitDefaultValue = false)]
internal long CompensationId
{
get;
set;
}
[DataMember(EmitDefaultValue = false)]
internal bool CompensateCalled
{
get;
set;
}
[DataMember(EmitDefaultValue = false)]
internal bool ConfirmCalled
{
get;
set;
}
}
}

View File

@@ -0,0 +1,88 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime;
using System.Diagnostics.CodeAnalysis;
using System.ComponentModel;
[Fx.Tag.XamlVisible(false)]
[DataContract]
class CompensationTokenData
{
internal CompensationTokenData(long compensationId, long parentCompensationId)
{
this.CompensationId = compensationId;
this.ParentCompensationId = parentCompensationId;
this.BookmarkTable = new BookmarkTable();
this.ExecutionTracker = new ExecutionTracker();
this.CompensationState = CompensationState.Creating;
}
[DataMember(EmitDefaultValue = false)]
internal long CompensationId
{
get;
set;
}
[DataMember(EmitDefaultValue = false)]
internal long ParentCompensationId
{
get;
set;
}
[DataMember]
internal BookmarkTable BookmarkTable
{
get;
set;
}
[DataMember]
internal ExecutionTracker ExecutionTracker
{
get;
set;
}
[DefaultValue(CompensationState.Active)]
[DataMember(EmitDefaultValue = false)]
internal CompensationState CompensationState
{
get;
set;
}
[DataMember(EmitDefaultValue = false)]
internal string DisplayName
{
get;
set;
}
[DataMember(EmitDefaultValue = false)]
internal bool IsTokenValidInSecondaryRoot
{
get;
set;
}
internal void RemoveBookmark(NativeActivityContext context, CompensationBookmarkName bookmarkName)
{
Bookmark bookmark = this.BookmarkTable[bookmarkName];
if (bookmark != null)
{
context.RemoveBookmark(bookmark);
this.BookmarkTable[bookmarkName] = null;
}
}
}
}

View File

@@ -0,0 +1,240 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime;
using System.Activities.Validation;
using System.Collections.ObjectModel;
using System.Linq;
using System.Activities.Expressions;
public sealed class Confirm : NativeActivity
{
static Constraint confirmWithNoTarget = Confirm.ConfirmWithNoTarget();
InternalConfirm internalConfirm;
DefaultConfirmation defaultConfirmation;
Variable<CompensationToken> currentCompensationToken;
public Confirm()
: base()
{
this.currentCompensationToken = new Variable<CompensationToken>();
}
public InArgument<CompensationToken> Target
{
get;
set;
}
DefaultConfirmation DefaultConfirmation
{
get
{
if (this.defaultConfirmation == null)
{
this.defaultConfirmation = new DefaultConfirmation()
{
Target = new InArgument<CompensationToken>(this.currentCompensationToken),
};
}
return this.defaultConfirmation;
}
}
InternalConfirm InternalConfirm
{
get
{
if (this.internalConfirm == null)
{
this.internalConfirm = new InternalConfirm()
{
Target = new InArgument<CompensationToken>(new ArgumentValue<CompensationToken> { ArgumentName = "Target" }),
};
}
return this.internalConfirm;
}
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
RuntimeArgument targetArgument = new RuntimeArgument("Target", typeof(CompensationToken), ArgumentDirection.In);
metadata.Bind(this.Target, targetArgument);
metadata.SetArgumentsCollection(
new Collection<RuntimeArgument>
{
targetArgument
});
metadata.SetImplementationVariablesCollection(
new Collection<Variable>
{
this.currentCompensationToken
});
Fx.Assert(DefaultConfirmation != null, "DefaultConfirmation must be valid");
Fx.Assert(InternalConfirm != null, "InternalConfirm must be valid");
metadata.SetImplementationChildrenCollection(
new Collection<Activity>
{
DefaultConfirmation,
InternalConfirm
});
}
internal override IList<Constraint> InternalGetConstraints()
{
return new List<Constraint>(1) { confirmWithNoTarget };
}
static Constraint ConfirmWithNoTarget()
{
DelegateInArgument<Confirm> element = new DelegateInArgument<Confirm> { Name = "element" };
DelegateInArgument<ValidationContext> validationContext = new DelegateInArgument<ValidationContext> { Name = "validationContext" };
Variable<bool> assertFlag = new Variable<bool> { Name = "assertFlag" };
Variable<IEnumerable<Activity>> elements = new Variable<IEnumerable<Activity>>() { Name = "elements" };
Variable<int> index = new Variable<int>() { Name = "index" };
return new Constraint<Confirm>
{
Body = new ActivityAction<Confirm, ValidationContext>
{
Argument1 = element,
Argument2 = validationContext,
Handler = new Sequence
{
Variables =
{
assertFlag,
elements,
index
},
Activities =
{
new If
{
Condition = new InArgument<bool>((env) => element.Get(env).Target != null),
Then = new Assign<bool>
{
To = assertFlag,
Value = true
},
Else = new Sequence
{
Activities =
{
new Assign<IEnumerable<Activity>>
{
To = elements,
Value = new GetParentChain
{
ValidationContext = validationContext,
},
},
new While(env => (assertFlag.Get(env) != true) &&
index.Get(env) < elements.Get(env).Count())
{
Body = new Sequence
{
Activities =
{
new If(env => (elements.Get(env).ElementAt(index.Get(env))).GetType() == typeof(CompensationParticipant))
{
Then = new Assign<bool>
{
To = assertFlag,
Value = true
},
},
new Assign<int>
{
To = index,
Value = new InArgument<int>(env => index.Get(env) + 1)
},
}
}
}
}
}
},
new AssertValidation
{
Assertion = new InArgument<bool>(assertFlag),
Message = new InArgument<string>(SR.ConfirmWithNoTargetConstraint)
}
}
}
}
};
}
protected override void Execute(NativeActivityContext context)
{
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
if (compensationExtension == null)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ConfirmWithoutCompensableActivity(this.DisplayName)));
}
if (Target.IsEmpty)
{
CompensationToken ambientCompensationToken = (CompensationToken)context.Properties.Find(CompensationToken.PropertyName);
CompensationTokenData ambientTokenData = ambientCompensationToken == null ? null : compensationExtension.Get(ambientCompensationToken.CompensationId);
if (ambientTokenData != null && ambientTokenData.IsTokenValidInSecondaryRoot)
{
this.currentCompensationToken.Set(context, ambientCompensationToken);
if (ambientTokenData.ExecutionTracker.Count > 0)
{
context.ScheduleActivity(DefaultConfirmation);
}
}
else
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.InvalidConfirmActivityUsage(this.DisplayName)));
}
}
else
{
CompensationToken compensationToken = Target.Get(context);
CompensationTokenData tokenData = compensationToken == null ? null : compensationExtension.Get(compensationToken.CompensationId);
if (compensationToken == null)
{
throw FxTrace.Exception.Argument("Target", SR.InvalidCompensationToken(this.DisplayName));
}
if (compensationToken.ConfirmCalled)
{
// No-Op
return;
}
if (tokenData == null || tokenData.CompensationState != CompensationState.Completed)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CompensableActivityAlreadyConfirmedOrCompensated));
}
// A valid in-arg was passed...
tokenData.CompensationState = CompensationState.Confirming;
compensationToken.ConfirmCalled = true;
context.ScheduleActivity(InternalConfirm);
}
}
protected override void Cancel(NativeActivityContext context)
{
// Suppress Cancel
}
}
}

View File

@@ -0,0 +1,31 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Activities;
using System.Runtime;
using System.Runtime.Serialization;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
public sealed class CreateBookmarkScope : NativeActivity<BookmarkScope>
{
public CreateBookmarkScope()
{
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
// NoOp - we override this to suppress reflection. The base class
// takes care of adding the Result argument.
}
protected override void Execute(NativeActivityContext context)
{
context.SetValue(this.Result, context.CreateBookmarkScope());
}
}
}

View File

@@ -0,0 +1,94 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Collections.Generic;
using System.Runtime;
using System.Collections.ObjectModel;
using SA = System.Activities;
sealed class DefaultCompensation : NativeActivity
{
Activity body;
Variable<CompensationToken> toCompensateToken;
CompletionCallback onChildCompensated;
public DefaultCompensation()
: base()
{
this.toCompensateToken = new Variable<CompensationToken>();
this.body = new InternalCompensate()
{
Target = new InArgument<CompensationToken>(toCompensateToken),
};
}
public InArgument<CompensationToken> Target
{
get;
set;
}
Activity Body
{
get { return this.body; }
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
RuntimeArgument targetArgument = new RuntimeArgument("Target", typeof(CompensationToken), ArgumentDirection.In);
metadata.Bind(this.Target, targetArgument);
metadata.SetArgumentsCollection(new Collection<RuntimeArgument> { targetArgument });
metadata.SetImplementationVariablesCollection(new Collection<Variable> { this.toCompensateToken });
Fx.Assert(this.Body != null, "Body must be valid");
metadata.SetImplementationChildrenCollection(new Collection<Activity> { this.Body });
}
protected override void Execute(NativeActivityContext context)
{
InternalExecute(context, null);
}
void InternalExecute(NativeActivityContext context, ActivityInstance completedInstance)
{
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
if (compensationExtension == null)
{
throw SA.FxTrace.Exception.AsError(new InvalidOperationException(SA.SR.CompensateWithoutCompensableActivity(this.DisplayName)));
}
CompensationToken token = Target.Get(context);
CompensationTokenData tokenData = token == null ? null : compensationExtension.Get(token.CompensationId);
Fx.Assert(tokenData != null, "CompensationTokenData must be valid");
if (tokenData.ExecutionTracker.Count > 0)
{
if (this.onChildCompensated == null)
{
this.onChildCompensated = new CompletionCallback(InternalExecute);
}
this.toCompensateToken.Set(context, new CompensationToken(tokenData.ExecutionTracker.Get()));
Fx.Assert(Body != null, "Body must be valid");
context.ScheduleActivity(Body, this.onChildCompensated);
}
}
protected override void Cancel(NativeActivityContext context)
{
// Suppress Cancel
}
}
}

View File

@@ -0,0 +1,90 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime;
sealed class DefaultConfirmation : NativeActivity
{
Activity body;
Variable<CompensationToken> toConfirmToken;
CompletionCallback onChildConfirmed;
public DefaultConfirmation()
: base()
{
this.toConfirmToken = new Variable<CompensationToken>();
this.body = new InternalConfirm()
{
Target = new InArgument<CompensationToken>(toConfirmToken),
};
}
public InArgument<CompensationToken> Target
{
get;
set;
}
Activity Body
{
get { return this.body; }
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
RuntimeArgument targetArgument = new RuntimeArgument("Target", typeof(CompensationToken), ArgumentDirection.In);
metadata.Bind(this.Target, targetArgument);
metadata.SetArgumentsCollection(new Collection<RuntimeArgument> { targetArgument });
metadata.SetImplementationVariablesCollection(new Collection<Variable> { this.toConfirmToken });
Fx.Assert(this.Body != null, "Body must be valid");
metadata.SetImplementationChildrenCollection(new Collection<Activity> { this.Body });
}
protected override void Execute(NativeActivityContext context)
{
InternalExecute(context, null);
}
void InternalExecute(NativeActivityContext context, ActivityInstance completedInstance)
{
CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>();
if (compensationExtension == null)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ConfirmWithoutCompensableActivity(this.DisplayName)));
}
CompensationToken token = Target.Get(context);
CompensationTokenData tokenData = token == null ? null : compensationExtension.Get(token.CompensationId);
Fx.Assert(tokenData != null, "CompensationTokenData must be valid");
if (tokenData.ExecutionTracker.Count > 0)
{
if (this.onChildConfirmed == null)
{
this.onChildConfirmed = new CompletionCallback(InternalExecute);
}
this.toConfirmToken.Set(context, new CompensationToken(tokenData.ExecutionTracker.Get()));
Fx.Assert(Body != null, "Body must be valid");
context.ScheduleActivity(Body, this.onChildConfirmed);
}
}
protected override void Cancel(NativeActivityContext context)
{
// Suppress Cancel
}
}
}

View File

@@ -0,0 +1,103 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Statements
{
using System;
using System.Activities;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime;
using System.Windows.Markup;
[ContentProperty("Duration")]
public sealed class Delay : NativeActivity
{
static Func<TimerExtension> getDefaultTimerExtension = new Func<TimerExtension>(GetDefaultTimerExtension);
Variable<Bookmark> timerBookmark;
public Delay()
: base()
{
this.timerBookmark = new Variable<Bookmark>();
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TimeSpan> Duration
{
get;
set;
}
protected override bool CanInduceIdle
{
get
{
return true;
}
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
RuntimeArgument durationArgument = new RuntimeArgument("Duration", typeof(TimeSpan), ArgumentDirection.In, true);
metadata.Bind(this.Duration, durationArgument);
metadata.SetArgumentsCollection(new Collection<RuntimeArgument> { durationArgument });
metadata.AddImplementationVariable(this.timerBookmark);
metadata.AddDefaultExtensionProvider(getDefaultTimerExtension);
}
static TimerExtension GetDefaultTimerExtension()
{
return new DurableTimerExtension();
}
protected override void Execute(NativeActivityContext context)
{
TimeSpan duration = this.Duration.Get(context);
if (duration < TimeSpan.Zero)
{
throw FxTrace.Exception.ArgumentOutOfRange("Duration", duration, SR.DurationIsNegative(this.DisplayName));
}
if (duration == TimeSpan.Zero)
{
return;
}
TimerExtension timerExtension = GetTimerExtension(context);
Bookmark bookmark = context.CreateBookmark();
timerExtension.RegisterTimer(duration, bookmark);
this.timerBookmark.Set(context, bookmark);
}
protected override void Cancel(NativeActivityContext context)
{
Bookmark timerBookmark = this.timerBookmark.Get(context);
TimerExtension timerExtension = GetTimerExtension(context);
timerExtension.CancelTimer(timerBookmark);
context.RemoveBookmark(timerBookmark);
context.MarkCanceled();
}
protected override void Abort(NativeActivityAbortContext context)
{
Bookmark timerBookmark = this.timerBookmark.Get(context);
// The bookmark could be null in abort when user passed in a negative delay as a duration
if (timerBookmark != null)
{
TimerExtension timerExtension = GetTimerExtension(context);
timerExtension.CancelTimer(timerBookmark);
}
base.Abort(context);
}
TimerExtension GetTimerExtension(ActivityContext context)
{
TimerExtension timerExtension = context.GetExtension<TimerExtension>();
Fx.Assert(timerExtension != null, "TimerExtension must exist.");
return timerExtension;
}
}
}

Some files were not shown because too many files have changed in this diff Show More