Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / Delay.cs / 1305376 / Delay.cs
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)]
public sealed class DelayActivity : Activity, IEventActivity, IActivityEventListener
{
#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 Implementation
void IActivityEventListener.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();
qService.GetWorkflowQueue(e.QueueName).Dequeue();
qService.DeleteWorkflowQueue(e.QueueName);
context.CloseActivity();
}
}
#endregion
#region IEventActivity implementation
void IEventActivity.Subscribe(ActivityExecutionContext parentContext, IActivityEventListener 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();
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 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();
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
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HeaderedItemsControl.cs
- SynchronizedDispatch.cs
- TextEditorLists.cs
- Root.cs
- RegexCompilationInfo.cs
- PromptStyle.cs
- OutputCacheProviderCollection.cs
- TransportElement.cs
- QilInvokeLateBound.cs
- WindowsTab.cs
- HttpCacheVary.cs
- _ContextAwareResult.cs
- ThaiBuddhistCalendar.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- ProcessHostConfigUtils.cs
- XmlRawWriter.cs
- SimplePropertyEntry.cs
- ColorMap.cs
- BinaryFormatterWriter.cs
- RequiredFieldValidator.cs
- ByteStreamMessageEncoderFactory.cs
- SymLanguageType.cs
- ByteViewer.cs
- SqlNodeTypeOperators.cs
- DetailsViewPageEventArgs.cs
- XmlSchemaSimpleType.cs
- OutputCacheSection.cs
- WindowsMenu.cs
- SystemSounds.cs
- TemplateControlParser.cs
- TagNameToTypeMapper.cs
- ProviderMetadata.cs
- RuleProcessor.cs
- DocumentAutomationPeer.cs
- PassportPrincipal.cs
- MatrixTransform.cs
- SqlWorkflowPersistenceService.cs
- DSACryptoServiceProvider.cs
- Calendar.cs
- CompilationLock.cs
- InputLanguageEventArgs.cs
- ObjRef.cs
- MediaPlayer.cs
- QueryContinueDragEventArgs.cs
- HoistedLocals.cs
- GraphicsState.cs
- DefaultWorkflowSchedulerService.cs
- FrugalList.cs
- SchemaExporter.cs
- RolePrincipal.cs
- VariableQuery.cs
- TimeIntervalCollection.cs
- EncodingInfo.cs
- TextElementCollection.cs
- CompilerGeneratedAttribute.cs
- HttpModuleActionCollection.cs
- ToolStripPanelSelectionGlyph.cs
- RelationalExpressions.cs
- MouseOverProperty.cs
- OutOfProcStateClientManager.cs
- mda.cs
- DataBindingList.cs
- LogReservationCollection.cs
- PackageDigitalSignature.cs
- SerializationEventsCache.cs
- BitStack.cs
- EpmCustomContentWriterNodeData.cs
- X500Name.cs
- LowerCaseStringConverter.cs
- Group.cs
- RuntimeVariableList.cs
- KeyEvent.cs
- FontSizeConverter.cs
- PropertyChangedEventArgs.cs
- SystemWebSectionGroup.cs
- StorageBasedPackageProperties.cs
- NameObjectCollectionBase.cs
- _HeaderInfo.cs
- UmAlQuraCalendar.cs
- SizeConverter.cs
- NullableLongSumAggregationOperator.cs
- RSAPKCS1KeyExchangeFormatter.cs
- WindowsListViewGroupHelper.cs
- KeyValuePairs.cs
- ToolStripManager.cs
- TdsParameterSetter.cs
- ReliabilityContractAttribute.cs
- MsmqIntegrationBindingElement.cs
- LayoutEditorPart.cs
- FileVersionInfo.cs
- EnumBuilder.cs
- SmtpException.cs
- AnnouncementDispatcherAsyncResult.cs
- XamlToRtfWriter.cs
- LinqDataSourceHelper.cs
- RoutedCommand.cs
- FocusWithinProperty.cs
- SqlClientWrapperSmiStreamChars.cs
- ScrollableControl.cs
- Brush.cs