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,52 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.ServiceModel.Channels;
using System.Globalization;
using System.Xml;
class DurableDispatcherAddressingFault : MessageFault
{
const string missingContextHeaderFaultName = "MissingContext";
FaultCode faultCode;
FaultReason faultReason;
public DurableDispatcherAddressingFault()
{
faultCode = FaultCode.CreateSenderFaultCode(missingContextHeaderFaultName, ContextMessageHeader.ContextHeaderNamespace);
faultReason = new FaultReason(new FaultReasonText(SR2.GetString(SR2.CurrentOperationCannotCreateInstance), CultureInfo.CurrentCulture));
}
public override FaultCode Code
{
get
{
return this.faultCode;
}
}
public override bool HasDetail
{
get
{
return false;
}
}
public override FaultReason Reason
{
get
{
return this.faultReason;
}
}
protected override void OnWriteDetailContents(XmlDictionaryWriter writer)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
}
}
}

View File

@ -0,0 +1,67 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.ServiceModel.Channels;
using System.Diagnostics.CodeAnalysis;
abstract class DurableErrorHandler : IErrorHandler
{
bool debug;
public DurableErrorHandler(bool debug)
{
this.debug = debug;
}
public static void CleanUpInstanceContextAtOperationCompletion()
{
if (OperationContext.Current == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.NoOperationContext));
}
DurableMessageDispatchInspector.SuppressContextOnReply(OperationContext.Current);
OperationContext.Current.InstanceContext.IncomingChannels.Clear();
}
public bool HandleError(Exception error)
{
return IsUserCodeException(error);
}
[SuppressMessage("Microsoft.Globalization", "CA1304")]
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
if (fault == null && IsUserCodeException(error))
{
FaultCode code = new FaultCode(FaultCodeConstants.Codes.InternalServiceFault, FaultCodeConstants.Namespaces.NetDispatch);
code = FaultCode.CreateReceiverFaultCode(code);
string action = FaultCodeConstants.Actions.NetDispatcher;
MessageFault messageFault;
if (this.debug)
{
Exception toTrace = GetExceptionToTrace(error);
messageFault = MessageFault.CreateFault(code, new FaultReason(toTrace.Message), new ExceptionDetail(toTrace));
}
else
{
string reason = SR.GetString(SR.SFxInternalServerError);
messageFault = MessageFault.CreateFault(code, new FaultReason(reason));
}
fault = Message.CreateMessage(version, messageFault, action);
}
}
protected virtual Exception GetExceptionToTrace(Exception error)
{
return error;
}
protected abstract bool IsUserCodeException(Exception error);
}
}

View File

@ -0,0 +1,89 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.Runtime;
using System.ServiceModel.Channels;
using System.ServiceModel.Persistence;
abstract class DurableInstance : CommunicationObject, IExtension<InstanceContext>
{
DurableInstanceContextProvider instanceContextProvider;
Guid instanceId;
protected DurableInstance(DurableInstanceContextProvider instanceContextProvider, Guid instanceId)
{
if (instanceContextProvider == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instanceContextProvider");
}
this.instanceId = instanceId;
this.instanceContextProvider = instanceContextProvider;
}
public Guid InstanceId
{
get
{
return this.instanceId;
}
}
protected override TimeSpan DefaultCloseTimeout
{
get { return PersistenceProvider.DefaultOpenClosePersistenceTimout; }
}
protected override TimeSpan DefaultOpenTimeout
{
get { return PersistenceProvider.DefaultOpenClosePersistenceTimout; }
}
public void DecrementActivityCount()
{
instanceContextProvider.DecrementActivityCount(this.instanceId);
}
void IExtension<InstanceContext>.Attach(InstanceContext owner)
{
}
void IExtension<InstanceContext>.Detach(InstanceContext owner)
{
}
protected override void OnAbort()
{
}
protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
{
return new CompletedAsyncResult(callback, state);
}
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
{
return new CompletedAsyncResult(callback, state);
}
protected override void OnClose(TimeSpan timeout)
{
}
protected override void OnEndClose(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
protected override void OnEndOpen(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
protected override void OnOpen(TimeSpan timeout)
{
}
}
}

View File

@ -0,0 +1,464 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.Collections.Generic;
using System.Runtime;
using System.Runtime.Diagnostics;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Diagnostics;
using System.Threading;
using System.Diagnostics;
abstract class DurableInstanceContextProvider : IInstanceContextProvider
{
ContextCache contextCache;
bool isPerCall;
ServiceHostBase serviceHostBase;
protected DurableInstanceContextProvider(ServiceHostBase serviceHostBase, bool isPerCall)
{
if (serviceHostBase == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceHostBase");
}
this.serviceHostBase = serviceHostBase;
if (serviceHostBase.Description.Behaviors.Find<ServiceThrottlingBehavior>() == null)
{
serviceHostBase.ServiceThrottle.MaxConcurrentInstances = (new ServiceThrottlingBehavior()).MaxConcurrentInstances;
}
this.contextCache = new ContextCache();
this.isPerCall = isPerCall;
}
protected ContextCache Cache
{
get
{
return this.contextCache;
}
}
public virtual InstanceContext GetExistingInstanceContext(Message message, IContextChannel channel)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
if (channel == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("channel");
}
Guid instanceId = GetInstanceIdFromMessage(message);
InstanceContext result = null;
if (instanceId != Guid.Empty) //Not an activation request.
{
if (contextCache.TryGetInstanceContext(instanceId, out result))
{
lock (result.ThisLock)
{
if (!string.IsNullOrEmpty(channel.SessionId) && !result.IncomingChannels.Contains(channel))
{
result.IncomingChannels.Add(channel);
}
}
return result;
}
}
return result;
}
public int GetReferenceCount(Guid instanceId)
{
return this.Cache.GetReferenceCount(instanceId);
}
public virtual void InitializeInstanceContext(InstanceContext instanceContext, Message message, IContextChannel channel)
{
if (instanceContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instanceContext");
}
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
if (channel == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("channel");
}
Guid instanceId = GetInstanceIdFromMessage(message);
DurableInstance durableInstance;
if (instanceId == Guid.Empty) //Activation Request.
{
instanceId = Guid.NewGuid();
durableInstance = this.OnCreateNewInstance(instanceId);
message.Properties[DurableMessageDispatchInspector.NewDurableInstanceIdPropertyName] = instanceId;
}
else
{
durableInstance = this.OnGetExistingInstance(instanceId);
}
Fx.Assert(durableInstance != null, "Durable instance should never be null at this point.");
durableInstance.Open();
instanceContext.Extensions.Add(durableInstance);
if (!string.IsNullOrEmpty(channel.SessionId))
{
instanceContext.IncomingChannels.Add(channel);
}
contextCache.AddInstanceContext(instanceId, instanceContext);
if (DiagnosticUtility.ShouldTraceInformation)
{
string traceText = SR.GetString(SR.TraceCodeDICPInstanceContextCached, instanceId);
TraceUtility.TraceEvent(TraceEventType.Information,
TraceCode.DICPInstanceContextCached, SR.GetString(SR.TraceCodeDICPInstanceContextCached),
new StringTraceRecord("InstanceDetail", traceText),
this, null);
}
}
public virtual bool IsIdle(InstanceContext instanceContext)
{
bool removed = false;
if (instanceContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instanceContext");
}
DurableInstance durableInstance = instanceContext.Extensions.Find<DurableInstance>();
if (durableInstance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(
SR2.RequiredInstanceContextExtensionNotFound,
typeof(DurableInstance).Name)));
}
lock (instanceContext.ThisLock)
{
if (instanceContext.IncomingChannels.Count == 0)
{
removed = contextCache.RemoveIfNotBusy(durableInstance.InstanceId, instanceContext);
}
}
if (removed && DiagnosticUtility.ShouldTraceInformation)
{
string traceText = SR.GetString(SR.TraceCodeDICPInstanceContextRemovedFromCache, durableInstance.InstanceId);
TraceUtility.TraceEvent(TraceEventType.Information,
TraceCode.DICPInstanceContextRemovedFromCache, SR.GetString(SR.TraceCodeDICPInstanceContextRemovedFromCache),
new StringTraceRecord("InstanceDetail", traceText),
this, null);
}
return removed;
}
public virtual void NotifyIdle(InstanceContextIdleCallback callback, InstanceContext instanceContext)
{
}
//Called by MessageInspector.BeforeReply
internal void DecrementActivityCount(Guid instanceId)
{
contextCache.ReleaseReference(instanceId);
}
internal void UnbindAbortedInstance(InstanceContext instanceContext, Guid instanceId)
{
if (instanceContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instanceContext");
}
//We made our best effor to clean up the instancecontext out of our cache.
//If another request already in middle of processing the request on InstanceContext
//It will Fail with CommunicationException.
this.contextCache.Remove(instanceId, instanceContext);
}
protected virtual Guid GetInstanceIdFromMessage(Message message)
{
if (!this.isPerCall)
{
ContextMessageProperty contextProperties = null;
string instanceId = null;
if (ContextMessageProperty.TryGet(message, out contextProperties))
{
if (contextProperties.Context.TryGetValue(WellKnownContextProperties.InstanceId, out instanceId))
{
return Fx.CreateGuid(instanceId);
}
}
}
return Guid.Empty;
}
protected abstract DurableInstance OnCreateNewInstance(Guid instanceId);
protected abstract DurableInstance OnGetExistingInstance(Guid instanceId);
//This class takes self contained lock, never calls out with lock taken.
protected class ContextCache
{
Dictionary<Guid, ContextItem> contextCache;
object lockObject = new object();
public ContextCache()
{
contextCache = new Dictionary<Guid, ContextItem>();
}
public void AddInstanceContext(Guid instanceId, InstanceContext instanceContext)
{
ContextItem contextItem;
int? referenceCount = null;
lock (lockObject)
{
if (!contextCache.TryGetValue(instanceId, out contextItem))
{
//This will be the case for activation request.
contextItem = new ContextItem(instanceId);
referenceCount = contextItem.AddReference();
contextCache.Add(instanceId, contextItem);
}
}
contextItem.InstanceContext = instanceContext;
if (DiagnosticUtility.ShouldTraceInformation && referenceCount.HasValue)
{
string traceText = SR2.GetString(SR2.DurableInstanceRefCountToInstanceContext, instanceId, referenceCount.Value);
TraceUtility.TraceEvent(TraceEventType.Information,
TraceCode.InstanceContextBoundToDurableInstance, SR.GetString(SR.TraceCodeInstanceContextBoundToDurableInstance),
new StringTraceRecord("InstanceDetail", traceText),
this, null);
}
}
public bool Contains(Guid instanceId, InstanceContext instanceContext)
{
ContextItem contextItem = null;
lock (this.lockObject)
{
if (contextCache.TryGetValue(instanceId, out contextItem))
{
return object.ReferenceEquals(contextItem.InstanceContext, instanceContext);
}
return false;
}
}
public int GetReferenceCount(Guid instanceId)
{
int result = 0;
lock (lockObject)
{
ContextItem contextItem;
if (contextCache.TryGetValue(instanceId, out contextItem))
{
result = contextItem.ReferenceCount;
}
}
return result;
}
public void ReleaseReference(Guid instanceId)
{
int referenceCount = -1;
ContextItem contextItem;
lock (lockObject)
{
if (contextCache.TryGetValue(instanceId, out contextItem))
{
referenceCount = contextItem.ReleaseReference();
}
else
{
Fx.Assert(false, "Cannot Release Reference of non exisiting items");
}
}
if (DiagnosticUtility.ShouldTraceInformation)
{
string traceText = SR2.GetString(SR2.DurableInstanceRefCountToInstanceContext, instanceId, referenceCount);
TraceUtility.TraceEvent(TraceEventType.Information,
TraceCode.InstanceContextDetachedFromDurableInstance, SR.GetString(SR.TraceCodeInstanceContextDetachedFromDurableInstance),
new StringTraceRecord("InstanceDetail", traceText),
this, null);
}
}
public bool Remove(Guid instanceId, InstanceContext instanceContext)
{
lock (this.lockObject)
{
ContextItem contextItem = null;
if (this.contextCache.TryGetValue(instanceId, out contextItem))
{
if (object.ReferenceEquals(instanceContext, contextItem.InstanceContext))
{
return this.contextCache.Remove(instanceId);
}
}
//InstanceContext is not in memory.
return false;
}
}
public bool RemoveIfNotBusy(Guid instanceId, InstanceContext instanceContext)
{
lock (lockObject)
{
ContextItem contextItem = null;
if (contextCache.TryGetValue(instanceId, out contextItem))
{
if (object.ReferenceEquals(contextItem.InstanceContext, instanceContext))
{
return (!contextItem.HasOutstandingReference)
&& (contextCache.Remove(instanceId));
}
}
//InstanceContext is not in memory.
return true;
}
}
//Helper method to call from GetExistingInstanceContext
//returns true : If InstanceContext is found in cache & guaranteed to stay in cache until ReleaseReference is called.
//returns false : If InstanceContext is not found in cache;
// reference & slot is created for the ID;
// InitializeInstanceContext to call AddInstanceContext.
public bool TryGetInstanceContext(Guid instanceId, out InstanceContext instanceContext)
{
ContextItem contextItem;
instanceContext = null;
int referenceCount = -1;
try
{
lock (lockObject)
{
if (!contextCache.TryGetValue(instanceId, out contextItem))
{
contextItem = new ContextItem(instanceId);
referenceCount = contextItem.AddReference();
contextCache.Add(instanceId, contextItem);
return false;
}
referenceCount = contextItem.AddReference();
}
}
finally
{
if (DiagnosticUtility.ShouldTraceInformation)
{
string traceText = SR2.GetString(SR2.DurableInstanceRefCountToInstanceContext, instanceId, referenceCount);
TraceUtility.TraceEvent(TraceEventType.Information,
TraceCode.InstanceContextBoundToDurableInstance, SR.GetString(SR.TraceCodeInstanceContextBoundToDurableInstance),
new StringTraceRecord("InstanceDetail", traceText),
this, null);
}
}
instanceContext = contextItem.InstanceContext;
return true;
}
class ContextItem
{
InstanceContext context;
Guid instanceId;
object lockObject;
int referenceCount;
public ContextItem(Guid instanceId)
{
lockObject = new object();
referenceCount = 0;
this.instanceId = instanceId;
}
public bool HasOutstandingReference
{
get
{
return this.referenceCount > 0;
}
}
public InstanceContext InstanceContext
{
get
{
if (this.context == null)
{
lock (this.lockObject)
{
if (this.context == null)
{
Monitor.Wait(this.lockObject);
}
}
}
Fx.Assert(this.context != null, "Context cannot be null at this point");
return this.context;
}
set
{
if (value == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
}
this.context = value;
lock (this.lockObject)
{
Monitor.PulseAll(this.lockObject);
}
}
}
public int ReferenceCount
{
get
{
return this.referenceCount;
}
}
public int AddReference()
{
//Called from higher locks taken
return ++this.referenceCount;
}
public int ReleaseReference()
{
Fx.Assert(referenceCount > 0, "Reference count gone to negative");
//Called from higher locks taken
return --this.referenceCount;
}
}
}
}
}

View File

@ -0,0 +1,57 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.ServiceModel.Channels;
class DurableInstanceProvider : IInstanceProvider
{
DurableInstanceContextProvider durableInstanceContextProvider;
public DurableInstanceProvider(DurableInstanceContextProvider instanceContextProvider)
{
this.durableInstanceContextProvider = instanceContextProvider;
}
public object GetInstance(InstanceContext instanceContext)
{
return ((IInstanceProvider) this).GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
if (instanceContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instanceContext");
}
return instanceContext.Extensions.Find<DurableInstance>();
}
public virtual void ReleaseInstance(InstanceContext instanceContext, object instance)
{
if (instanceContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instanceContext");
}
if (instance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instance");
}
DurableInstance durableInstance = (DurableInstance) instance;
if (instanceContext.State == CommunicationState.Faulted || instanceContext.Aborted)
{
durableInstance.Abort();
this.durableInstanceContextProvider.UnbindAbortedInstance(instanceContext, durableInstance.InstanceId);
}
else if (instanceContext.State == CommunicationState.Closed)
{
durableInstance.Close();
}
}
}
}

View File

@ -0,0 +1,105 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.ServiceModel.Channels;
class DurableMessageDispatchInspector : IDispatchMessageInspector
{
public const string NewDurableInstanceIdPropertyName = "newDurableInstanceIdProperty";
const string suppressContextOnReply = "suppressContextOnReply";
SessionMode sessionMode;
public DurableMessageDispatchInspector(SessionMode sessionMode)
{
this.sessionMode = sessionMode;
}
public static void SuppressContextOnReply(OperationContext operationContext)
{
if (operationContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operationContext");
}
operationContext.OutgoingMessageProperties[suppressContextOnReply] = true;
}
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
if (instanceContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instanceContext");
}
if (request == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("request");
}
if (sessionMode != SessionMode.NotAllowed)
{
object result = null;
if (request.Properties.TryGetValue(NewDurableInstanceIdPropertyName, out result))
{
return result.ToString();
}
}
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
try
{
if (reply != null)
{
ContextMessageProperty context = null;
if (sessionMode == SessionMode.NotAllowed || reply.Properties.ContainsKey(suppressContextOnReply))
{
if (ContextMessageProperty.TryGet(reply, out context))
{
context.Context.Clear();
}
}
else
{
string newInstanceId = correlationState as string;
if (newInstanceId != null)
{
if (!ContextMessageProperty.TryGet(reply, out context))
{
context = new ContextMessageProperty();
context.Context[WellKnownContextProperties.InstanceId] = newInstanceId;
context.AddOrReplaceInMessage(reply);
}
else
{
context.Context[WellKnownContextProperties.InstanceId] = newInstanceId;
}
}
}
}
}
finally
{
DurableInstance durableInstance = OperationContext.Current.InstanceContext.Extensions.Find<DurableInstance>();
if (durableInstance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(
SR2.RequiredInstanceContextExtensionNotFound,
typeof(DurableInstance).Name)));
}
//Decrement InstanceActivity Count
durableInstance.DecrementActivityCount();
}
}
}
}

View File

@ -0,0 +1,123 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.ServiceModel.Description;
[Obsolete("The WF3 types are deprecated. Instead, please use the new WF4 types from System.Activities.*")]
public static class DurableOperationContext
{
public static Guid InstanceId
{
get
{
ServiceDurableInstance durableInstance = GetInstanceContextExtension();
return durableInstance.InstanceId;
}
}
public static void AbortInstance()
{
ServiceDurableInstance durableInstance = GetInstanceContextExtension();
durableInstance.AbortInstance();
}
public static void CompleteInstance()
{
ServiceDurableInstance durableInstance = GetInstanceContextExtension();
durableInstance.MarkForCompletion();
}
internal static void BeginOperation()
{
OperationContext operationContext = OperationContext.Current;
if (operationContext != null)
{
operationContext.Extensions.Add(new DurableOperationContext.IsInOperation());
}
}
internal static void EndOperation()
{
OperationContext operationContext = OperationContext.Current;
if (operationContext != null)
{
DurableOperationContext.IsInOperation isInOperation = operationContext.Extensions.Find<DurableOperationContext.IsInOperation>();
if (isInOperation != null)
{
operationContext.Extensions.Remove(isInOperation);
}
}
}
static ServiceDurableInstance GetInstanceContextExtension()
{
OperationContext operationContext = OperationContext.Current;
if (operationContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(
SR2.OnlyCallableFromServiceOperation,
typeof(DurableOperationContext).Name)));
}
IsInOperation isInOperation = operationContext.Extensions.Find<IsInOperation>();
if (isInOperation == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(
SR2.OnlyCallableWhileInOperation,
typeof(DurableOperationContext).Name)));
}
InstanceContext currentInstanceContext = operationContext.InstanceContext;
if (currentInstanceContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(
SR2.OnlyCallableFromServiceOperation,
typeof(DurableOperationContext).Name)));
}
ServiceDurableInstance durableInstance =
currentInstanceContext.Extensions.Find<ServiceDurableInstance>();
if (durableInstance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(
SR2.OnlyCallableFromDurableService,
typeof(DurableOperationContext).Name,
typeof(DurableServiceAttribute).Name)));
}
return durableInstance;
}
class IsInOperation : IExtension<OperationContext>
{
public void Attach(OperationContext owner)
{
}
public void Detach(OperationContext owner)
{
}
}
}
}

View File

@ -0,0 +1,76 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.ServiceModel.Description;
using System.Workflow.Runtime;
using System.Runtime;
class DurableRuntimeValidator
{
ConcurrencyMode concurrencyMode;
UnknownExceptionAction exceptionAction;
bool saveStateInOperationTransaction;
bool validated;
public DurableRuntimeValidator(bool saveStateInOperationTransaction, UnknownExceptionAction exceptionAction)
{
this.saveStateInOperationTransaction = saveStateInOperationTransaction;
this.exceptionAction = exceptionAction;
this.validated = false;
}
public ConcurrencyMode ConcurrencyMode
{
get
{
if (!this.validated)
{
ValidateRuntime();
}
return concurrencyMode;
}
}
public void ValidateRuntime()
{
if (!this.validated)
{
Fx.Assert(
OperationContext.Current != null &&
OperationContext.Current.EndpointDispatcher != null &&
OperationContext.Current.EndpointDispatcher.DispatchRuntime != null,
"There shouldn't have been a null value in " +
"OperationContext.Current.EndpointDispatcher.DispatchRuntime.");
this.concurrencyMode = OperationContext.Current.EndpointDispatcher.DispatchRuntime.ConcurrencyMode;
if (this.concurrencyMode == ConcurrencyMode.Multiple)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(SR2.ConcurrencyMultipleNotSupported)));
}
if (this.saveStateInOperationTransaction && this.concurrencyMode != ConcurrencyMode.Single)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(SR2.SaveStateInTransactionRequiresSingle)));
}
if (this.concurrencyMode == ConcurrencyMode.Reentrant
&& this.exceptionAction == UnknownExceptionAction.AbortInstance)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(SR2.ConcurrencyReentrantAndAbortNotSupported)));
}
this.validated = true;
}
}
}
}

View File

@ -0,0 +1,92 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Persistence;
using System.Threading;
using System.ServiceModel.Description;
using System.ServiceModel.Diagnostics;
using System.Diagnostics;
using System.Runtime.Diagnostics;
class ServiceDurableInstanceContextProvider : DurableInstanceContextProvider
{
TimeSpan operationTimeout;
PersistenceProviderFactory providerFactory;
DurableRuntimeValidator runtimeValidator;
bool saveStateInOperationTransaction;
Type serviceType;
UnknownExceptionAction unknownExceptionAction;
public ServiceDurableInstanceContextProvider(
ServiceHostBase serviceHostBase,
bool isPercall,
Type serviceType,
PersistenceProviderFactory providerFactory,
bool saveStateInOperationTransaction,
UnknownExceptionAction unknownExceptionAction,
DurableRuntimeValidator runtimeValidator,
TimeSpan operationTimeout)
: base(serviceHostBase, isPercall)
{
if (serviceType == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceType");
}
if (providerFactory == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("providerFactory");
}
if (runtimeValidator == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("runtimeValidator");
}
this.serviceType = serviceType;
this.providerFactory = providerFactory;
this.saveStateInOperationTransaction = saveStateInOperationTransaction;
this.unknownExceptionAction = unknownExceptionAction;
this.runtimeValidator = runtimeValidator;
this.operationTimeout = operationTimeout;
}
protected override DurableInstance OnCreateNewInstance(Guid instanceId)
{
if (DiagnosticUtility.ShouldTraceInformation)
{
string traceText = SR2.GetString(SR2.InstanceContextProviderCreatedNewInstance, "Service", instanceId);
TraceUtility.TraceEvent(TraceEventType.Information,
TraceCode.ActivatingMessageReceived, SR.GetString(SR.TraceCodeActivatingMessageReceived),
new StringTraceRecord("NewInstanceDetail", traceText),
this, null);
}
return new ServiceDurableInstance(
this.providerFactory.CreateProvider(instanceId),
this,
this.saveStateInOperationTransaction,
this.unknownExceptionAction,
this.runtimeValidator,
this.operationTimeout,
this.serviceType);
}
protected override DurableInstance OnGetExistingInstance(Guid instanceId)
{
return new ServiceDurableInstance(
this.providerFactory.CreateProvider(instanceId),
this,
this.saveStateInOperationTransaction,
this.unknownExceptionAction,
this.runtimeValidator,
this.operationTimeout);
}
}
}

View File

@ -0,0 +1,43 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.ServiceModel.Channels;
using System.Collections;
class ServiceErrorHandler : DurableErrorHandler
{
const string dataKey = "System.ServiceModel.Dispatcher.ServiceErrorHandler.MarkExeption";
public ServiceErrorHandler(bool debug)
: base(debug)
{
}
public static void MarkException(Exception toMark)
{
// From MSDN: The OutOfMemoryException, StackOverflowException and ThreadAbortException
// classes always return a null reference for the value of the Data property.
// These are fatal exceptions and therefore we don't care that we can't mark them.
IDictionary data = toMark.Data;
if (data != null && !data.IsReadOnly && !data.IsFixedSize)
{
data.Add(dataKey, true);
}
}
protected override bool IsUserCodeException(Exception error)
{
IDictionary data = error.Data;
if (data != null && data.Contains(dataKey))
{
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,334 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime;
using System.ServiceModel.Description;
using System.ServiceModel.Diagnostics;
class ServiceOperationInvoker : IOperationInvoker
{
bool canCreateInstance;
bool completesInstance;
bool contractCausesSave;
IOperationInvoker innerInvoker;
public ServiceOperationInvoker(IOperationInvoker innerInvoker, bool completesInstance, bool canCreateInstance, bool contractCausesSave)
{
if (innerInvoker == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("innerInvoker");
}
this.innerInvoker = innerInvoker;
this.completesInstance = completesInstance;
this.canCreateInstance = canCreateInstance;
this.contractCausesSave = contractCausesSave;
}
public bool IsSynchronous
{
get { return this.innerInvoker.IsSynchronous; }
}
public object[] AllocateInputs()
{
return this.innerInvoker.AllocateInputs();
}
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
if (instance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instance");
}
ServiceDurableInstance durableInstance = instance as ServiceDurableInstance;
if (durableInstance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(SR2.InvokeCalledWithWrongType, typeof(DurableServiceAttribute).Name)));
}
object serviceInstance = durableInstance.StartOperation(this.canCreateInstance);
Exception operationException = null;
bool failFast = false;
try
{
return this.innerInvoker.Invoke(serviceInstance, inputs, out outputs);
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
failFast = true;
throw;
}
operationException = e;
ServiceErrorHandler.MarkException(e);
throw;
}
finally
{
if (!failFast)
{
durableInstance.FinishOperation(this.completesInstance, this.contractCausesSave, operationException);
}
}
}
public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
{
if (instance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instance");
}
ServiceDurableInstance durableInstance = instance as ServiceDurableInstance;
if (durableInstance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(SR2.InvokeCalledWithWrongType, typeof(DurableServiceAttribute).Name)));
}
return new InvokeAsyncResult(durableInstance, inputs, this, this.canCreateInstance, callback, state);
}
public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
{
return InvokeAsyncResult.End(out outputs, result);
}
public class InvokeAsyncResult : AsyncResult
{
static AsyncCallback finishCallback = Fx.ThunkCallback(new AsyncCallback(FinishComplete));
static AsyncCallback invokeCallback = Fx.ThunkCallback(new AsyncCallback(InvokeComplete));
static AsyncCallback startCallback = Fx.ThunkCallback(new AsyncCallback(StartComplete));
Exception completionException;
ServiceDurableInstance durableInstance;
object[] inputs;
ServiceOperationInvoker invoker;
OperationContext operationContext;
object[] outputs;
object returnValue;
object serviceInstance;
public InvokeAsyncResult(ServiceDurableInstance instance, object[] inputs, ServiceOperationInvoker invoker, bool canCreateInstance, AsyncCallback callback, object state)
: base(callback, state)
{
this.invoker = invoker;
this.inputs = inputs;
this.durableInstance = instance;
this.operationContext = OperationContext.Current;
IAsyncResult result = this.durableInstance.BeginStartOperation(canCreateInstance, startCallback, this);
if (result.CompletedSynchronously)
{
this.serviceInstance = this.durableInstance.EndStartOperation(result);
if (DoInvoke())
{
Complete(true, this.completionException);
}
}
}
public static object End(out object[] outputs, IAsyncResult result)
{
InvokeAsyncResult invokeResult = AsyncResult.End<InvokeAsyncResult>(result);
outputs = invokeResult.outputs;
return invokeResult.returnValue;
}
// We pass the exception to another thread
[SuppressMessage("Reliability", "Reliability104")]
[SuppressMessage("Microsoft.Design", "CA1031")]
static void FinishComplete(IAsyncResult result)
{
if (result.CompletedSynchronously)
{
return;
}
InvokeAsyncResult invokeResult = result.AsyncState as InvokeAsyncResult;
Fx.Assert(invokeResult != null, "Async state should have been of type InvokeAsyncResult.");
try
{
invokeResult.durableInstance.EndFinishOperation(result);
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
invokeResult.completionException = e;
}
invokeResult.Complete(false, invokeResult.completionException);
}
// We pass the exception to another thread
[SuppressMessage("Reliability", "Reliability104")]
[SuppressMessage("Microsoft.Design", "CA1031")]
static void InvokeComplete(IAsyncResult resultParameter)
{
if (resultParameter.CompletedSynchronously)
{
return;
}
InvokeAsyncResult invokeResult = resultParameter.AsyncState as InvokeAsyncResult;
Fx.Assert(invokeResult != null,
"Async state should have been of type InvokeAsyncResult.");
try
{
invokeResult.returnValue = invokeResult.invoker.innerInvoker.InvokeEnd(invokeResult.serviceInstance, out invokeResult.outputs, resultParameter);
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
ServiceErrorHandler.MarkException(e);
invokeResult.completionException = e;
}
finally
{
if (invokeResult.DoFinish())
{
invokeResult.Complete(false, invokeResult.completionException);
}
}
}
// We pass the exception to another thread
[SuppressMessage("Reliability", "Reliability104")]
[SuppressMessage("Microsoft.Design", "CA1031")]
static void StartComplete(IAsyncResult resultParameter)
{
if (resultParameter.CompletedSynchronously)
{
return;
}
InvokeAsyncResult invokeResult = resultParameter.AsyncState as InvokeAsyncResult;
Fx.Assert(invokeResult != null,
"Async state should have been of type InvokeAsyncResult.");
try
{
invokeResult.serviceInstance = invokeResult.durableInstance.EndStartOperation(resultParameter);
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
invokeResult.Complete(false, e);
return;
}
if (invokeResult.DoInvoke())
{
invokeResult.Complete(false, invokeResult.completionException);
}
}
// We pass the exception to another thread
[SuppressMessage("Reliability", "Reliability104")]
[SuppressMessage("Microsoft.Design", "CA1031")]
bool DoFinish()
{
try
{
IAsyncResult result = this.durableInstance.BeginFinishOperation(this.invoker.completesInstance, this.invoker.contractCausesSave, this.completionException, finishCallback, this);
if (result.CompletedSynchronously)
{
this.durableInstance.EndFinishOperation(result);
return true;
}
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
this.completionException = e;
return true;
}
return false;
}
// We pass the exception to another thread
[SuppressMessage("Reliability", "Reliability104")]
[SuppressMessage("Microsoft.Design", "CA1031")]
bool DoInvoke()
{
bool finishNow = false;
try
{
IAsyncResult result = null;
using (OperationContextScope operationScope = new OperationContextScope(this.operationContext))
{
result = this.invoker.innerInvoker.InvokeBegin(this.serviceInstance, this.inputs, invokeCallback, this);
}
if (result.CompletedSynchronously)
{
this.returnValue = this.invoker.innerInvoker.InvokeEnd(this.serviceInstance, out this.outputs, result);
finishNow = true;
}
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
ServiceErrorHandler.MarkException(e);
this.completionException = e;
finishNow = true;
}
if (finishNow)
{
if (DoFinish())
{
return true;
}
}
return false;
}
}
}
}

View File

@ -0,0 +1,12 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
static class WellKnownContextProperties
{
public const string ConversationId = "conversationId";
public const string InstanceId = "instanceId";
}
}

View File

@ -0,0 +1,59 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.Threading;
using System.Collections.Generic;
class WorkflowDispatchContext : IDisposable
{
[ThreadStatic]
static WorkflowDispatchContext workflowDispatchContext = null;
bool isWorkflowStarting;
bool synchronous;
public WorkflowDispatchContext(bool synchronous)
: this(synchronous, false)
{
// empty
}
public WorkflowDispatchContext(bool synchronous, bool isWorkflowStarting)
{
this.synchronous = synchronous;
this.isWorkflowStarting = isWorkflowStarting;
workflowDispatchContext = this;
}
public static WorkflowDispatchContext Current
{
get
{
return workflowDispatchContext;
}
}
public bool IsSynchronous
{
get
{
return this.synchronous;
}
}
public bool IsWorkflowStarting
{
get
{
return this.isWorkflowStarting;
}
}
public void Dispose()
{
workflowDispatchContext = null;
}
}
}

View File

@ -0,0 +1,102 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.Workflow.Runtime;
using System.Runtime.Diagnostics;
using System.ServiceModel.Diagnostics;
using System.Diagnostics;
class WorkflowDurableInstance : DurableInstance
{
WorkflowOperationAsyncResult currentOperationInvocation;
WorkflowInstanceContextProvider instanceContextProvider;
bool shouldCreateNew = false;
object thisLock = new object();
WorkflowDefinitionContext workflowDefinition;
WorkflowInstance workflowInstance = null;
public WorkflowDurableInstance(WorkflowInstanceContextProvider instanceContextProvider, Guid instanceId, WorkflowDefinitionContext workflowDefinition, bool createNew)
:
base(instanceContextProvider, instanceId)
{
if (workflowDefinition == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("workflowDefinition");
}
this.workflowDefinition = workflowDefinition;
this.shouldCreateNew = createNew;
this.instanceContextProvider = instanceContextProvider;
}
public WorkflowOperationAsyncResult CurrentOperationInvocation
{
get
{
return this.currentOperationInvocation;
}
set
{
this.currentOperationInvocation = value;
}
}
public WorkflowInstance GetWorkflowInstance(bool canCreateInstance)
{
if (this.workflowInstance == null)
{
lock (thisLock)
{
if (shouldCreateNew)
{
if (canCreateInstance)
{
this.workflowInstance = this.workflowDefinition.CreateWorkflow(this.InstanceId);
shouldCreateNew = false;
if (DiagnosticUtility.ShouldTraceInformation)
{
string traceText = SR.GetString(SR.TraceCodeWorkflowDurableInstanceActivated, InstanceId);
TraceUtility.TraceEvent(TraceEventType.Information,
TraceCode.WorkflowDurableInstanceActivated, traceText,
new StringTraceRecord("DurableInstanceDetail", traceText),
this, null);
}
using (new WorkflowDispatchContext(true, true))
{
this.workflowInstance.Start();
}
}
else
{
//Make sure we clean up this InstanceContext;
DurableErrorHandler.CleanUpInstanceContextAtOperationCompletion();
//Inform InstanceLifeTimeManager to clean up record for InstanceId;
if (this.instanceContextProvider.InstanceLifeTimeManager != null)
{
this.instanceContextProvider.InstanceLifeTimeManager.CleanUp(this.InstanceId);
}
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FaultException(new DurableDispatcherAddressingFault()));
}
}
else
{
this.workflowInstance = this.workflowDefinition.WorkflowRuntime.GetWorkflow(InstanceId);
if (DiagnosticUtility.ShouldTraceInformation)
{
string traceText = SR.GetString(SR.TraceCodeWorkflowDurableInstanceLoaded, InstanceId);
TraceUtility.TraceEvent(TraceEventType.Information,
TraceCode.WorkflowDurableInstanceLoaded, traceText,
new StringTraceRecord("DurableInstanceDetail", traceText),
this, null);
}
}
}
}
return workflowInstance;
}
}
}

View File

@ -0,0 +1,295 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.Runtime;
using System.Runtime.Diagnostics;
using System.ServiceModel.Channels;
using System.ServiceModel.Diagnostics;
using System.Threading;
using System.Workflow.Runtime;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics;
class WorkflowInstanceContextProvider : DurableInstanceContextProvider
{
bool hasCheckedForExtension;
WorkflowInstanceLifetimeManagerExtension instanceLifeTimeManager;
ServiceHostBase serviceHostBase;
WaitCallback workflowActivationCompleteCallback;
WorkflowDefinitionContext workflowDefinitionContext;
public WorkflowInstanceContextProvider(ServiceHostBase serviceHostBase, bool isPerCall, WorkflowDefinitionContext workflowDefinitionContext)
: base(serviceHostBase, isPerCall)
{
if (workflowDefinitionContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("workflowDefinitionContext");
}
this.workflowDefinitionContext = workflowDefinitionContext;
this.serviceHostBase = serviceHostBase;
this.workflowActivationCompleteCallback = Fx.ThunkCallback(new WaitCallback(this.OnWorkflowActivationCompleted));
}
public WorkflowInstanceLifetimeManagerExtension InstanceLifeTimeManager
{
get
{
if (!hasCheckedForExtension)
{
this.instanceLifeTimeManager = this.serviceHostBase.Extensions.Find<WorkflowInstanceLifetimeManagerExtension>();
hasCheckedForExtension = true;
}
return this.instanceLifeTimeManager;
}
}
public override InstanceContext GetExistingInstanceContext(Message message, IContextChannel channel)
{
InstanceContext instanceContext = base.GetExistingInstanceContext(message, channel);
if (instanceContext != null && this.InstanceLifeTimeManager != null)
{
WorkflowDurableInstance workflowDurableInstance = instanceContext.Extensions.Find<WorkflowDurableInstance>();
if (workflowDurableInstance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(
SR2.RequiredInstanceContextExtensionNotFound,
typeof(WorkflowDurableInstance).Name)));
}
this.InstanceLifeTimeManager.NotifyWorkflowActivationComplete(
workflowDurableInstance.InstanceId,
this.workflowActivationCompleteCallback,
new WorkflowActivationCompletedCallbackState
(
workflowDurableInstance.InstanceId,
instanceContext),
false);
}
return instanceContext;
}
public override void InitializeInstanceContext(InstanceContext instanceContext, Message message, IContextChannel channel)
{
base.InitializeInstanceContext(instanceContext, message, channel);
WorkflowDurableInstance workflowDurableInstance = instanceContext.Extensions.Find<WorkflowDurableInstance>();
if (workflowDurableInstance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(
SR2.RequiredInstanceContextExtensionNotFound,
typeof(WorkflowDurableInstance).Name)));
}
if (this.InstanceLifeTimeManager != null)
{
this.InstanceLifeTimeManager.NotifyWorkflowActivationComplete(workflowDurableInstance.InstanceId,
this.workflowActivationCompleteCallback,
new WorkflowActivationCompletedCallbackState
(workflowDurableInstance.InstanceId, instanceContext),
false);
}
}
public override bool IsIdle(InstanceContext instanceContext)
{
if (instanceContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instanceContext");
}
WorkflowDurableInstance workflowDurableInstance = instanceContext.Extensions.Find<WorkflowDurableInstance>();
if (workflowDurableInstance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(
SR2.RequiredInstanceContextExtensionNotFound,
typeof(WorkflowDurableInstance).Name)));
}
if (this.InstanceLifeTimeManager != null)
{
return (!this.InstanceLifeTimeManager.IsInstanceInMemory(workflowDurableInstance.InstanceId)) &&
base.IsIdle(instanceContext);
}
return base.IsIdle(instanceContext);
}
public override void NotifyIdle(InstanceContextIdleCallback callback, InstanceContext instanceContext)
{
WorkflowDurableInstance workflowDurableInstance = instanceContext.Extensions.Find<WorkflowDurableInstance>();
if (workflowDurableInstance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(
SR2.RequiredInstanceContextExtensionNotFound,
typeof(WorkflowDurableInstance).Name)));
}
if (this.InstanceLifeTimeManager != null)
{
if (this.InstanceLifeTimeManager.IsInstanceInMemory(workflowDurableInstance.InstanceId))
{
this.InstanceLifeTimeManager.NotifyWorkflowActivationComplete(workflowDurableInstance.InstanceId,
Fx.ThunkCallback(new WaitCallback(this.OnWorkflowActivationCompleted)),
new WorkflowActivationCompletedCallbackState
(
workflowDurableInstance.InstanceId,
instanceContext,
callback),
true);
}
else
{
if (base.IsIdle(instanceContext))
{
callback(instanceContext);
}
else
{
base.NotifyIdle(callback, instanceContext);
}
}
}
else
{
base.NotifyIdle(callback, instanceContext);
}
}
protected override DurableInstance OnCreateNewInstance(Guid instanceId)
{
if (DiagnosticUtility.ShouldTraceInformation)
{
string traceText = SR2.GetString(SR2.InstanceContextProviderCreatedNewInstance, "Workflow", instanceId);
TraceUtility.TraceEvent(TraceEventType.Information,
TraceCode.ActivatingMessageReceived, SR.GetString(SR.TraceCodeActivatingMessageReceived),
new StringTraceRecord("NewInstanceDetail", traceText),
this, null);
}
return new WorkflowDurableInstance(this, instanceId, this.workflowDefinitionContext, true);
}
protected override DurableInstance OnGetExistingInstance(Guid instanceId)
{
return new WorkflowDurableInstance(this, instanceId, this.workflowDefinitionContext, false);
}
void OnWorkflowActivationCompleted(object state)
{
WorkflowActivationCompletedCallbackState callbackState = (WorkflowActivationCompletedCallbackState) state;
lock (callbackState.InstanceContext.ThisLock)
{
if (base.Cache.Contains(callbackState.InstanceId, callbackState.InstanceContext))
{
WorkflowDurableInstance durableInstance = callbackState.InstanceContext.Extensions.Find<WorkflowDurableInstance>();
if (durableInstance != null
&& durableInstance.CurrentOperationInvocation != null
&& durableInstance.CurrentOperationInvocation.HasWorkflowRequestContextBeenSerialized
&& !durableInstance.CurrentOperationInvocation.IsCompleted)
{
// If we are here, it means the workflow instance completed, terminated, or otherwise unloaded without
// completing the current operation invocation. In such case, we want to make the best effort to let
// service model to consider this operation invocation failed.
try
{
durableInstance.CurrentOperationInvocation.SendFault(
WorkflowOperationErrorHandler.CreateUnhandledException(
new InvalidOperationException(SR2.GetString(SR2.WorkflowServiceUnloadedWithoutSendingResponse))),
null);
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
}
}
IChannel[] incomingChannels = new IChannel[callbackState.InstanceContext.IncomingChannels.Count];
callbackState.InstanceContext.IncomingChannels.CopyTo(incomingChannels, 0);
if (callbackState.InstanceContext.IncomingChannels.Count != 0)
{
foreach (IChannel channel in incomingChannels)
{
callbackState.InstanceContext.IncomingChannels.Remove(channel);
}
}
else
{
//Call notify only when IncomingChannels Collection is empty.
if (callbackState.InstanceContextIdleCallback != null)
{
callbackState.InstanceContextIdleCallback(callbackState.InstanceContext);
}
}
}
}
}
class WorkflowActivationCompletedCallbackState
{
InstanceContext instanceContext;
InstanceContextIdleCallback instanceContextIdleCallback;
Guid instanceId;
public WorkflowActivationCompletedCallbackState(Guid instanceId, InstanceContext instanceContext)
: this(instanceId, instanceContext, null)
{
}
public WorkflowActivationCompletedCallbackState(Guid instanceId, InstanceContext instanceContext, InstanceContextIdleCallback callback)
{
this.instanceId = instanceId;
this.instanceContext = instanceContext;
this.instanceContextIdleCallback = callback;
}
public InstanceContext InstanceContext
{
get
{
return this.instanceContext;
}
}
public InstanceContextIdleCallback InstanceContextIdleCallback
{
get
{
return this.instanceContextIdleCallback;
}
}
public Guid InstanceId
{
get
{
return this.instanceId;
}
}
}
}
}

View File

@ -0,0 +1,394 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.Collections.Generic;
using System.Runtime;
using System.Runtime.Diagnostics;
using System.ServiceModel.Diagnostics;
using System.Threading;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Diagnostics;
class WorkflowInstanceLifetimeManagerExtension : IExtension<ServiceHostBase>
{
readonly Action<object> cachedInstanceExpirationTimerCallback;
TimeSpan cachedInstanceExpiration;
bool hasPersistenceService;
Dictionary<Guid, InstanceRecord> instanceRecordMap;
//This class takes self contained lock, never calls out external method with lock taken.
object lockObject;
WorkflowRuntime workflowRuntime;
public WorkflowInstanceLifetimeManagerExtension(WorkflowRuntime workflowRuntime, TimeSpan cachedInstanceExpiration, bool hasPersistenceService)
{
this.workflowRuntime = workflowRuntime;
this.cachedInstanceExpiration = cachedInstanceExpiration;
this.instanceRecordMap = new Dictionary<Guid, InstanceRecord>();
this.lockObject = new object();
this.cachedInstanceExpirationTimerCallback = new Action<object>(this.OnTimer);
this.hasPersistenceService = hasPersistenceService;
RegisterEvents();
}
//This is called when InstanceContext is taken down behind us;
//1. UnhandledException causing InstanceContext to Abort;
//2. Activating Request to Non-Activating operation;
public void CleanUp(Guid instanceId)
{
//If no WorkflowInstance actively running for this InstanceId;
//This will be last opportunity to cleanup their record; to avoid
//growth of this HashTable.
InstanceRecord instanceRecord;
lock (this.lockObject)
{
if (this.instanceRecordMap.TryGetValue(instanceId, out instanceRecord))
{
if (!instanceRecord.InstanceLoadedOrStarted)
{
if (instanceRecord.UnloadTimer != null)
{
instanceRecord.UnloadTimer.Cancel();
}
this.instanceRecordMap.Remove(instanceId);
}
}
}
}
void IExtension<ServiceHostBase>.Attach(ServiceHostBase owner)
{
}
void IExtension<ServiceHostBase>.Detach(ServiceHostBase owner)
{
}
public bool IsInstanceInMemory(Guid instanceId)
{
InstanceRecord instanceRecord;
lock (this.lockObject)
{
if (instanceRecordMap.TryGetValue(instanceId, out instanceRecord))
{
return instanceRecord.InstanceLoadedOrStarted;
}
}
return false;
}
//Assumption: Message arrived means; instance turned to Executing state.
public void NotifyMessageArrived(Guid instanceId)
{
CancelTimer(instanceId, false);
}
public void NotifyWorkflowActivationComplete(Guid instanceId, WaitCallback callback, object state, bool fireImmediatelyIfDontExist)
{
bool instanceFound;
InstanceRecord instanceRecord;
lock (this.lockObject)
{
instanceFound = instanceRecordMap.TryGetValue(instanceId, out instanceRecord);
if (instanceFound)
{
instanceRecord.Callback = callback;
instanceRecord.CallbackState = state;
}
else if (!fireImmediatelyIfDontExist)
{
instanceRecord = new InstanceRecord();
instanceRecord.Callback = callback;
instanceRecord.CallbackState = state;
instanceRecordMap.Add(instanceId, instanceRecord);
}
}
if (!instanceFound && fireImmediatelyIfDontExist)
{
//Instance is not in-memory; Notify immediately.
callback(state);
}
}
public void ScheduleTimer(Guid instanceId)
{
InstanceRecord instanceRecord;
lock (this.lockObject)
{
if (this.instanceRecordMap.TryGetValue(instanceId, out instanceRecord))
{
if (instanceRecord.UnloadTimer != null)
{
instanceRecord.UnloadTimer.Cancel();
}
else
{
instanceRecord.UnloadTimer = new IOThreadTimer(this.cachedInstanceExpirationTimerCallback, instanceId, true);
}
instanceRecord.UnloadTimer.Set(this.cachedInstanceExpiration);
}
}
}
void CancelTimer(Guid instanceId, bool markActivationCompleted)
{
InstanceRecord instanceRecord;
WaitCallback callback = null;
object callbackState = null;
lock (this.lockObject)
{
if (instanceRecordMap.TryGetValue(instanceId, out instanceRecord))
{
if (instanceRecord.UnloadTimer != null)
{
instanceRecord.UnloadTimer.Cancel();
instanceRecord.UnloadTimer = null;
}
if (markActivationCompleted)
{
instanceRecordMap.Remove(instanceId);
callback = instanceRecord.Callback;
callbackState = instanceRecord.CallbackState;
}
}
}
if (callback != null)
{
callback(callbackState);
}
}
void OnTimer(object state)
{
Guid instanceId = (Guid) state;
try
{
if (this.hasPersistenceService)
{
this.workflowRuntime.GetWorkflow(instanceId).TryUnload();
}
else
{
this.workflowRuntime.GetWorkflow(instanceId).Abort();
if (DiagnosticUtility.ShouldTraceInformation)
{
string traceText = SR2.GetString(SR2.AutoAbortingInactiveInstance, instanceId);
TraceUtility.TraceEvent(TraceEventType.Information,
TraceCode.WorkflowDurableInstanceAborted, SR.GetString(SR.TraceCodeWorkflowDurableInstanceAborted),
new StringTraceRecord("InstanceDetail", traceText),
this, null);
}
}
}
catch (PersistenceException)
{
try
{
this.workflowRuntime.GetWorkflow(instanceId).Abort();
if (DiagnosticUtility.ShouldTraceInformation)
{
string traceText = SR2.GetString(SR2.AutoAbortingInactiveInstance, instanceId);
TraceUtility.TraceEvent(TraceEventType.Information,
TraceCode.WorkflowDurableInstanceAborted, SR.GetString(SR.TraceCodeWorkflowDurableInstanceAborted),
new StringTraceRecord("InstanceDetail", traceText),
this, null);
}
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
}
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
}
}
void OnWorkflowAborted(object sender, WorkflowEventArgs args)
{
if (args == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("args");
}
CancelTimer(args.WorkflowInstance.InstanceId, true);
}
void OnWorkflowCompleted(object sender, WorkflowCompletedEventArgs args)
{
if (args == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("args");
}
CancelTimer(args.WorkflowInstance.InstanceId, true);
}
void OnWorkflowIdled(object sender, WorkflowEventArgs args)
{
if (args == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("args");
}
ScheduleTimer(args.WorkflowInstance.InstanceId);
}
void OnWorkflowLoaded(object sender, WorkflowEventArgs args)
{
if (args == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("args");
}
InstanceRecord instanceRecord;
lock (this.lockObject)
{
if (!this.instanceRecordMap.TryGetValue(args.WorkflowInstance.InstanceId, out instanceRecord))
{
instanceRecord = new InstanceRecord();
this.instanceRecordMap.Add(args.WorkflowInstance.InstanceId, instanceRecord);
}
instanceRecord.InstanceLoadedOrStarted = true;
}
}
void OnWorkflowStarted(object sender, WorkflowEventArgs args)
{
if (args == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("args");
}
InstanceRecord instanceRecord;
lock (this.lockObject)
{
if (!this.instanceRecordMap.TryGetValue(args.WorkflowInstance.InstanceId, out instanceRecord))
{
instanceRecord = new InstanceRecord();
this.instanceRecordMap.Add(args.WorkflowInstance.InstanceId, instanceRecord);
}
instanceRecord.InstanceLoadedOrStarted = true;
}
}
void OnWorkflowTerminated(object sender, WorkflowTerminatedEventArgs args)
{
if (args == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("args");
}
CancelTimer(args.WorkflowInstance.InstanceId, true);
}
void OnWorkflowUnloaded(object sender, WorkflowEventArgs args)
{
if (args == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("args");
}
CancelTimer(args.WorkflowInstance.InstanceId, true);
}
void RegisterEvents()
{
//Events marking the beggining of activation cycle.
this.workflowRuntime.WorkflowLoaded += OnWorkflowLoaded;
this.workflowRuntime.WorkflowCreated += OnWorkflowStarted;
//Events marking the end of activation cycle.
this.workflowRuntime.WorkflowAborted += OnWorkflowAborted;
this.workflowRuntime.WorkflowCompleted += OnWorkflowCompleted;
this.workflowRuntime.WorkflowTerminated += OnWorkflowTerminated;
this.workflowRuntime.WorkflowUnloaded += OnWorkflowUnloaded;
//Event which triggers the idle unload timer.
this.workflowRuntime.WorkflowIdled += OnWorkflowIdled;
}
class InstanceRecord
{
object callbackState;
WaitCallback instanceActivationCompletedCallBack;
bool loadedOrStarted = false;
IOThreadTimer unloadTimer;
public WaitCallback Callback
{
get
{
return this.instanceActivationCompletedCallBack;
}
set
{
this.instanceActivationCompletedCallBack = value;
}
}
public object CallbackState
{
get
{
return this.callbackState;
}
set
{
this.callbackState = value;
}
}
public bool InstanceLoadedOrStarted
{
get
{
return this.loadedOrStarted;
}
set
{
this.loadedOrStarted = value;
}
}
public IOThreadTimer UnloadTimer
{
get
{
return this.unloadTimer;
}
set
{
this.unloadTimer = value;
}
}
}
}
}

View File

@ -0,0 +1,34 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
class WorkflowInstanceProvider : DurableInstanceProvider
{
WorkflowInstanceContextProvider instanceContextProvider;
public WorkflowInstanceProvider(WorkflowInstanceContextProvider instanceContextProvider)
: base(instanceContextProvider)
{
this.instanceContextProvider = instanceContextProvider;
}
public override void ReleaseInstance(InstanceContext instanceContext, object instance)
{
WorkflowDurableInstance workflowDurableInstance = null;
//If InstanceContext is taken down due to Exception(Like PersistenceException);
//Make sure we inform LifeTimeManager to cleanup the record.
if (instanceContext.State == CommunicationState.Faulted || instanceContext.Aborted)
{
if (this.instanceContextProvider.InstanceLifeTimeManager != null)
{
workflowDurableInstance = (WorkflowDurableInstance) instance;
this.instanceContextProvider.InstanceLifeTimeManager.CleanUp(workflowDurableInstance.InstanceId);
}
}
base.ReleaseInstance(instanceContext, instance);
}
}
}

View File

@ -0,0 +1,391 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.Collections.Generic;
using System.Runtime;
using System.Runtime.Diagnostics;
using System.ServiceModel.Channels;
using System.ServiceModel.Diagnostics;
using System.Threading;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Diagnostics;
sealed class WorkflowOperationAsyncResult : AsyncResult
{
static readonly object[] emptyObjectArray = new object[] { };
static Action<object> waitCallback = new Action<object>(WorkflowOperationAsyncResult.DoWork);
static SendOrPostCallback sendOrPostCallback = Fx.ThunkCallback(new SendOrPostCallback(waitCallback));
Guid instanceIdGuid;
string instanceIdString;
bool isOneway;
IDictionary<string, string> outgoingContextProperties = SerializableReadOnlyDictionary<string, string>.Empty;
object[] outputs = emptyObjectArray;
object returnValue;
long time;
public WorkflowOperationAsyncResult(WorkflowOperationInvoker workflowOperationInvoker,
WorkflowDurableInstance workflowDurableInstance, object[] inputs,
AsyncCallback callback, object state, long time)
: base(callback, state)
{
if (inputs == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inputs");
}
if (workflowDurableInstance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("workflowDurableInstance");
}
if (workflowOperationInvoker == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("workflowOperationInvoker");
}
string queueName;
WorkflowRequestContext workflowRequestContext = new WorkflowRequestContext(
this,
inputs,
GetContextProperties());
queueName = workflowOperationInvoker.StaticQueueName;
if (workflowRequestContext.ContextProperties.Count > 1) //DurableDispatchContextProperty.
{
queueName = QueueNameHelper.Create(workflowOperationInvoker.StaticQueueName, workflowRequestContext.ContextProperties);
}
WorkflowInstance workflowInstance = workflowDurableInstance.GetWorkflowInstance
(workflowOperationInvoker.CanCreateInstance);
AsyncCallbackState callbackState = new AsyncCallbackState(workflowRequestContext,
workflowInstance, workflowOperationInvoker.DispatchRuntime.SynchronizationContext,
workflowOperationInvoker.InstanceLifetimeManager, queueName);
this.isOneway = workflowOperationInvoker.IsOneWay;
this.instanceIdGuid = workflowInstance.InstanceId;
this.time = time;
ActionItem.Schedule(waitCallback, callbackState);
if (DiagnosticUtility.ShouldTraceVerbose)
{
string traceText = SR2.GetString(SR2.WorkflowOperationInvokerItemQueued, this.InstanceId, queueName);
TraceUtility.TraceEvent(TraceEventType.Verbose,
TraceCode.WorkflowOperationInvokerItemQueued, SR.GetString(SR.TraceCodeWorkflowOperationInvokerItemQueued),
new StringTraceRecord("ItemDetails", traceText),
this, null);
}
}
public long BeginTime
{
get
{
return this.time;
}
}
public bool HasWorkflowRequestContextBeenSerialized
{
get;
set;
}
internal string InstanceId
{
get
{
if (this.instanceIdString == null)
{
Fx.Assert(!this.instanceIdGuid.Equals(Guid.Empty), "WorkflowOperationInvokerAsyncResut.instanceIdGuid != Guid.Empty");
this.instanceIdString = this.instanceIdGuid.ToString();
}
return this.instanceIdString;
}
}
public static object End(WorkflowOperationAsyncResult result, out object[] outputs)
{
if (result == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
}
try
{
AsyncResult.End<WorkflowOperationAsyncResult>(result);
}
finally
{
//Application Fault's should carry Context Properties
result.PromoteContextProperties();
}
outputs = result.outputs;
return result.returnValue;
}
public void SendFault(Exception exception, IDictionary<string, string> contextProperties)
{
if (exception == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exception");
}
if (!IsCompleted)
{
this.outgoingContextProperties = (contextProperties != null) ? new ContextDictionary(contextProperties) : null;
}
base.Complete(false, exception);
}
public void SendResponse(object returnValue, object[] outputs, IDictionary<string, string> contextProperties)
{
if (outputs == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("outputs");
}
if (!IsCompleted)
{
this.returnValue = returnValue;
this.outputs = outputs;
this.outgoingContextProperties = (contextProperties != null) ? new ContextDictionary(contextProperties) : null;
}
base.Complete(false);
}
//No-op for two-ways.
internal void MarkOneWayOperationCompleted()
{
if (this.isOneway && !this.IsCompleted)
{
base.Complete(false);
}
}
static void DoWork(object state)
{
if (state == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("state");
}
AsyncCallbackState callbackState = (AsyncCallbackState) state;
bool executingWork = false;
try
{
//If SyncContext is enabled
//We have to do another post to get to correct thread.
if (callbackState.SynchronizationContext != null)
{
SynchronizationContext synchronizationContext = callbackState.SynchronizationContext;
callbackState.SynchronizationContext = null;
SynchronizationContextWorkflowSchedulerService.SynchronizationContextPostHelper.Post(
synchronizationContext,
WorkflowOperationAsyncResult.sendOrPostCallback,
callbackState);
}
else //We are in correct thread to do the work.
{
using (new WorkflowDispatchContext(true))
{
callbackState.WorkflowRequestContext.SetOperationBegin();
executingWork = true;
if (callbackState.WorkflowInstanceLifeTimeManager != null)
{
callbackState.WorkflowInstanceLifeTimeManager.NotifyMessageArrived(callbackState.WorkflowInstance.InstanceId);
}
callbackState.WorkflowInstance.EnqueueItemOnIdle(
callbackState.QueueName,
callbackState.WorkflowRequestContext,
null,
null);
}
}
}
catch (QueueException e)
{
WorkflowOperationFault operationFault = new WorkflowOperationFault(e.ErrorCode);
try
{
if (callbackState.WorkflowInstanceLifeTimeManager != null)
{
callbackState.WorkflowInstanceLifeTimeManager.ScheduleTimer(callbackState.WorkflowInstance.InstanceId);
}
callbackState.WorkflowRequestContext.SendFault(new FaultException(operationFault), null);
}
catch (Exception unhandled)
{
if (Fx.IsFatal(unhandled))
{
throw;
}
// ignore exception; we made best effort to propagate the exception back to the invoker thread
}
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
try
{
if (callbackState.WorkflowInstanceLifeTimeManager != null)
{
callbackState.WorkflowInstanceLifeTimeManager.ScheduleTimer(callbackState.WorkflowInstance.InstanceId);
}
//We should field only user code exception; Everything else should go abort path.
callbackState.WorkflowRequestContext.GetAsyncResult().SendFault(e, null);
}
catch (Exception e1)
{
if (Fx.IsFatal(e1))
{
throw;
}
// ignore exception; we made best effort to propagate the exception back to the invoker thread
}
}
finally
{
try
{
if (executingWork)
{
callbackState.WorkflowRequestContext.SetOperationCompleted();
}
}
catch (Exception e1)
{
if (Fx.IsFatal(e1))
{
throw;
}
// ignore exception; we made best effort to propagate the exception back to the invoker thread }
}
}
}
IDictionary<string, string> GetContextProperties()
{
Fx.Assert(OperationContext.Current != null, "Called from non service thread");
ContextMessageProperty incomingContextProperties = null;
if (OperationContext.Current.IncomingMessageProperties != null
&& ContextMessageProperty.TryGet(OperationContext.Current.IncomingMessageProperties, out incomingContextProperties))
{
return incomingContextProperties.Context;
}
else
{
return SerializableReadOnlyDictionary<string, string>.Empty;
}
}
void PromoteContextProperties()
{
Fx.Assert(OperationContext.Current != null, "Called from non service thread");
if (outgoingContextProperties != null)
{
ContextMessageProperty context;
if (!ContextMessageProperty.TryGet(OperationContext.Current.OutgoingMessageProperties, out context))
{
new ContextMessageProperty(this.outgoingContextProperties).AddOrReplaceInMessageProperties(OperationContext.Current.OutgoingMessageProperties);
}
else
{
foreach (KeyValuePair<string, string> contextElement in this.outgoingContextProperties)
{
context.Context[contextElement.Key] = contextElement.Value;
}
}
}
}
class AsyncCallbackState
{
WorkflowInstanceLifetimeManagerExtension instanceLifeTimeManager;
IComparable queueName;
SynchronizationContext synchronizationContext;
WorkflowInstance workflowInstance;
WorkflowRequestContext workflowRequestContext;
public AsyncCallbackState(
WorkflowRequestContext workflowRequestContext,
WorkflowInstance workflowInstance,
SynchronizationContext synchronizationContext,
WorkflowInstanceLifetimeManagerExtension instanceLifeTimeManager,
IComparable queueName)
{
this.workflowInstance = workflowInstance;
this.workflowRequestContext = workflowRequestContext;
this.synchronizationContext = synchronizationContext;
this.queueName = queueName;
this.instanceLifeTimeManager = instanceLifeTimeManager;
}
public IComparable QueueName
{
get
{
return this.queueName;
}
}
public SynchronizationContext SynchronizationContext
{
get
{
return this.synchronizationContext;
}
set
{
this.synchronizationContext = value;
}
}
public WorkflowInstance WorkflowInstance
{
get
{
return this.workflowInstance;
}
}
public WorkflowInstanceLifetimeManagerExtension WorkflowInstanceLifeTimeManager
{
get
{
return this.instanceLifeTimeManager;
}
}
public WorkflowRequestContext WorkflowRequestContext
{
get
{
return this.workflowRequestContext;
}
}
}
}
}

View File

@ -0,0 +1,44 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.ServiceModel.Channels;
class WorkflowOperationErrorHandler : DurableErrorHandler
{
public WorkflowOperationErrorHandler(bool includeDebugInfo)
: base(includeDebugInfo)
{
}
public static Exception CreateUnhandledException(Exception innerException)
{
if (innerException == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("innerException");
}
return new WorkflowOperationUnhandledException(innerException);
}
protected override Exception GetExceptionToTrace(Exception error)
{
return error.InnerException;
}
protected override bool IsUserCodeException(Exception error)
{
return error is WorkflowOperationUnhandledException;
}
class WorkflowOperationUnhandledException : Exception
{
public WorkflowOperationUnhandledException(Exception innerException)
: base(SR2.GetString(SR2.WorkflowOperationUnhandledException), innerException)
{
}
}
}
}

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