You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
380
mcs/class/referencesource/System.Workflow.Activities/Delay.cs
Normal file
380
mcs/class/referencesource/System.Workflow.Activities/Delay.cs
Normal file
@ -0,0 +1,380 @@
|
||||
namespace System.Workflow.Activities
|
||||
{
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.CodeDom;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Drawing;
|
||||
using System.Workflow.ComponentModel;
|
||||
using System.Workflow.ComponentModel.Design;
|
||||
using System.Collections.Generic;
|
||||
using System.Workflow.Runtime;
|
||||
using System.Workflow.Runtime.Hosting;
|
||||
using System.Workflow.ComponentModel.Compiler;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Workflow.Activities.Common;
|
||||
|
||||
[SRDescription(SR.DelayActivityDescription)]
|
||||
[ToolboxItem(typeof(ActivityToolboxItem))]
|
||||
[Designer(typeof(DelayDesigner), typeof(IDesigner))]
|
||||
[ToolboxBitmap(typeof(DelayActivity), "Resources.Delay.png")]
|
||||
[DefaultEvent("InitializeTimeoutDuration")]
|
||||
[ActivityValidator(typeof(DelayActivityValidator))]
|
||||
[SRCategory(SR.Standard)]
|
||||
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
|
||||
public sealed class DelayActivity : Activity, IEventActivity, IActivityEventListener<QueueEventArgs>
|
||||
{
|
||||
#region Public Dependency Properties
|
||||
public static readonly DependencyProperty InitializeTimeoutDurationEvent = DependencyProperty.Register("InitializeTimeoutDuration", typeof(EventHandler), typeof(DelayActivity));
|
||||
public static readonly DependencyProperty TimeoutDurationProperty = DependencyProperty.Register("TimeoutDuration", typeof(TimeSpan), typeof(DelayActivity), new PropertyMetadata(new TimeSpan(0, 0, 0)));
|
||||
#endregion
|
||||
#region Private Dependency Properties
|
||||
private static readonly DependencyProperty QueueNameProperty = DependencyProperty.Register("QueueName", typeof(IComparable), typeof(DelayActivity));
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public DelayActivity()
|
||||
{
|
||||
}
|
||||
|
||||
public DelayActivity(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Handlers
|
||||
[SRCategory(SR.Handlers)]
|
||||
[SRDescription(SR.TimeoutInitializerDescription)]
|
||||
[MergableProperty(false)]
|
||||
public event EventHandler InitializeTimeoutDuration
|
||||
{
|
||||
add
|
||||
{
|
||||
base.AddHandler(InitializeTimeoutDurationEvent, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
base.RemoveHandler(InitializeTimeoutDurationEvent, value);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public Properties
|
||||
[SRDescription(SR.TimeoutDurationDescription)]
|
||||
[MergableProperty(false)]
|
||||
[TypeConverter(typeof(TimeoutDurationConverter))]
|
||||
public TimeSpan TimeoutDuration
|
||||
{
|
||||
get
|
||||
{
|
||||
return (TimeSpan)base.GetValue(TimeoutDurationProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
base.SetValue(TimeoutDurationProperty, value);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected override void Initialize(IServiceProvider provider)
|
||||
{
|
||||
base.Initialize(provider);
|
||||
|
||||
// Define the queue name for this Delay
|
||||
this.SetValue(QueueNameProperty, Guid.NewGuid());
|
||||
}
|
||||
|
||||
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
|
||||
{
|
||||
if (executionContext == null)
|
||||
throw new ArgumentNullException("executionContext");
|
||||
|
||||
if (this.IsInEventActivityMode)
|
||||
{
|
||||
return ActivityExecutionStatus.Closed;
|
||||
}
|
||||
else
|
||||
{
|
||||
((IEventActivity)this).Subscribe(executionContext, this);
|
||||
this.IsInEventActivityMode = false;
|
||||
return ActivityExecutionStatus.Executing;
|
||||
}
|
||||
}
|
||||
|
||||
protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext)
|
||||
{
|
||||
if (executionContext == null)
|
||||
throw new ArgumentNullException("executionContext");
|
||||
|
||||
if (!this.IsInEventActivityMode)
|
||||
{
|
||||
if (this.SubscriptionID != Guid.Empty)
|
||||
{
|
||||
((IEventActivity)this).Unsubscribe(executionContext, this);
|
||||
}
|
||||
}
|
||||
return ActivityExecutionStatus.Closed;
|
||||
}
|
||||
|
||||
protected sealed override ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception)
|
||||
{
|
||||
if (executionContext == null)
|
||||
throw new ArgumentNullException("executionContext");
|
||||
|
||||
if (exception == null)
|
||||
throw new ArgumentNullException("exception");
|
||||
|
||||
ActivityExecutionStatus newStatus = this.Cancel(executionContext);
|
||||
if (newStatus == ActivityExecutionStatus.Canceling)
|
||||
return ActivityExecutionStatus.Faulting;
|
||||
|
||||
return newStatus;
|
||||
}
|
||||
|
||||
protected override void OnClosed(IServiceProvider provider)
|
||||
{
|
||||
base.RemoveProperty(DelayActivity.SubscriptionIDProperty);
|
||||
base.RemoveProperty(DelayActivity.IsInEventActivityModeProperty);
|
||||
}
|
||||
|
||||
private class DelayActivityValidator : ActivityValidator
|
||||
{
|
||||
public override ValidationErrorCollection Validate(ValidationManager manager, object obj)
|
||||
{
|
||||
ValidationErrorCollection errors = new ValidationErrorCollection();
|
||||
|
||||
DelayActivity delay = obj as DelayActivity;
|
||||
if (delay == null)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
if (delay.TimeoutDuration.Ticks < 0)
|
||||
{
|
||||
errors.Add(new ValidationError(SR.GetString(SR.Error_NegativeValue, new object[] { delay.TimeoutDuration.ToString(), "TimeoutDuration" }), ErrorNumbers.Error_NegativeValue));
|
||||
}
|
||||
|
||||
errors.AddRange(base.Validate(manager, obj));
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Implementation
|
||||
#region Runtime Data / Properties
|
||||
static DependencyProperty SubscriptionIDProperty = DependencyProperty.Register("SubscriptionID", typeof(Guid), typeof(DelayActivity), new PropertyMetadata(Guid.NewGuid()));
|
||||
static DependencyProperty IsInEventActivityModeProperty = DependencyProperty.Register("IsInEventActivityMode", typeof(bool), typeof(DelayActivity), new PropertyMetadata(false));
|
||||
|
||||
private Guid SubscriptionID
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Guid)base.GetValue(DelayActivity.SubscriptionIDProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
base.SetValue(DelayActivity.SubscriptionIDProperty, value);
|
||||
}
|
||||
}
|
||||
private bool IsInEventActivityMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)base.GetValue(DelayActivity.IsInEventActivityModeProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
base.SetValue(DelayActivity.IsInEventActivityModeProperty, value);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Timeout Duration Conversion Helper
|
||||
private sealed class TimeoutDurationConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(string))
|
||||
return true;
|
||||
|
||||
return base.CanConvertTo(context, destinationType);
|
||||
}
|
||||
|
||||
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(string) && value is TimeSpan)
|
||||
{
|
||||
TimeSpan timespan = (TimeSpan)value;
|
||||
return timespan.ToString();
|
||||
}
|
||||
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
if (sourceType == typeof(string))
|
||||
return true;
|
||||
|
||||
return base.CanConvertFrom(context, sourceType);
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
|
||||
{
|
||||
object parsedTimespan = TimeSpan.Zero;
|
||||
string timeSpan = value as string;
|
||||
if (!String.IsNullOrEmpty(timeSpan))
|
||||
{
|
||||
//If this fails then an exception is thrown and the property set would fail
|
||||
try
|
||||
{
|
||||
parsedTimespan = TimeSpan.Parse(timeSpan, CultureInfo.InvariantCulture);
|
||||
if (parsedTimespan != null && ((TimeSpan)parsedTimespan).Ticks < 0)
|
||||
throw new Exception(string.Format(System.Globalization.CultureInfo.CurrentCulture, SR.GetString(SR.Error_NegativeValue), value.ToString(), "TimeoutDuration"));
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new Exception(SR.GetString(SR.InvalidTimespanFormat, timeSpan));
|
||||
}
|
||||
}
|
||||
|
||||
return parsedTimespan;
|
||||
}
|
||||
|
||||
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
|
||||
{
|
||||
ArrayList standardValuesCollection = new ArrayList();
|
||||
standardValuesCollection.Add(new TimeSpan(0, 0, 0));
|
||||
standardValuesCollection.Add(new TimeSpan(0, 1, 0));
|
||||
standardValuesCollection.Add(new TimeSpan(0, 30, 0));
|
||||
standardValuesCollection.Add(new TimeSpan(1, 0, 0));
|
||||
standardValuesCollection.Add(new TimeSpan(12, 0, 0));
|
||||
standardValuesCollection.Add(new TimeSpan(1, 0, 0, 0));
|
||||
|
||||
return new StandardValuesCollection(standardValuesCollection);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region IActivityEventListener<QueueEventArgs> Implementation
|
||||
void IActivityEventListener<QueueEventArgs>.OnEvent(object sender, QueueEventArgs e)
|
||||
{
|
||||
if (sender == null)
|
||||
throw new ArgumentNullException("sender");
|
||||
if (e == null)
|
||||
throw new ArgumentNullException("e");
|
||||
|
||||
ActivityExecutionContext context = sender as ActivityExecutionContext;
|
||||
|
||||
if (context == null)
|
||||
throw new ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender");
|
||||
|
||||
if (this.ExecutionStatus != ActivityExecutionStatus.Closed)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(this.SubscriptionID != Guid.Empty);
|
||||
|
||||
WorkflowQueuingService qService = context.GetService<WorkflowQueuingService>();
|
||||
qService.GetWorkflowQueue(e.QueueName).Dequeue();
|
||||
qService.DeleteWorkflowQueue(e.QueueName);
|
||||
context.CloseActivity();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IEventActivity implementation
|
||||
void IEventActivity.Subscribe(ActivityExecutionContext parentContext, IActivityEventListener<QueueEventArgs> parentEventHandler)
|
||||
{
|
||||
if (parentContext == null)
|
||||
throw new ArgumentNullException("parentContext");
|
||||
if (parentEventHandler == null)
|
||||
throw new ArgumentNullException("parentEventHandler");
|
||||
|
||||
this.IsInEventActivityMode = true;
|
||||
|
||||
base.RaiseEvent(DelayActivity.InitializeTimeoutDurationEvent, this, EventArgs.Empty);
|
||||
TimeSpan timeSpan = this.TimeoutDuration;
|
||||
DateTime timeOut = DateTime.UtcNow + timeSpan;
|
||||
|
||||
WorkflowQueuingService qService = parentContext.GetService<WorkflowQueuingService>();
|
||||
|
||||
IComparable queueName = ((IEventActivity)this).QueueName;
|
||||
TimerEventSubscription timerSub = new TimerEventSubscription((Guid)queueName, this.WorkflowInstanceId, timeOut);
|
||||
WorkflowQueue queue = qService.CreateWorkflowQueue(queueName, false);
|
||||
|
||||
queue.RegisterForQueueItemAvailable(parentEventHandler, this.QualifiedName);
|
||||
this.SubscriptionID = timerSub.SubscriptionId;
|
||||
|
||||
Activity root = this;
|
||||
while (root.Parent != null)
|
||||
root = root.Parent;
|
||||
|
||||
TimerEventSubscriptionCollection timers = (TimerEventSubscriptionCollection)root.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty);
|
||||
Debug.Assert(timers != null, "TimerEventSubscriptionCollection on root activity should never be null, but it was");
|
||||
timers.Add(timerSub);
|
||||
}
|
||||
|
||||
void IEventActivity.Unsubscribe(ActivityExecutionContext parentContext, IActivityEventListener<QueueEventArgs> parentEventHandler)
|
||||
{
|
||||
if (parentContext == null)
|
||||
throw new ArgumentNullException("parentContext");
|
||||
if (parentEventHandler == null)
|
||||
throw new ArgumentNullException("parentEventHandler");
|
||||
|
||||
System.Diagnostics.Debug.Assert(this.SubscriptionID != Guid.Empty);
|
||||
WorkflowQueuingService qService = parentContext.GetService<WorkflowQueuingService>();
|
||||
WorkflowQueue wfQueue = null;
|
||||
|
||||
try
|
||||
{
|
||||
wfQueue = qService.GetWorkflowQueue(this.SubscriptionID);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If the queue no longer exists, eat the exception, we clear the subscription id later.
|
||||
}
|
||||
|
||||
if (wfQueue != null && wfQueue.Count != 0)
|
||||
wfQueue.Dequeue();
|
||||
|
||||
// WinOE Bug 16929: In the case of dynamic update, if this activity is being removed,
|
||||
// we can not trace back to the root activity from "this".
|
||||
Activity root = parentContext.Activity;
|
||||
while (root.Parent != null)
|
||||
root = root.Parent;
|
||||
TimerEventSubscriptionCollection timers = (TimerEventSubscriptionCollection)root.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty);
|
||||
Debug.Assert(timers != null, "TimerEventSubscriptionCollection on root activity should never be null, but it was");
|
||||
timers.Remove(this.SubscriptionID);
|
||||
|
||||
if (wfQueue != null)
|
||||
{
|
||||
wfQueue.UnregisterForQueueItemAvailable(parentEventHandler);
|
||||
qService.DeleteWorkflowQueue(this.SubscriptionID);
|
||||
}
|
||||
|
||||
this.SubscriptionID = Guid.Empty;
|
||||
}
|
||||
|
||||
IComparable IEventActivity.QueueName
|
||||
{
|
||||
get
|
||||
{
|
||||
return (IComparable)this.GetValue(QueueNameProperty);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user