Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / Executors / WorkflowWebService.cs / 1305376 / WorkflowWebService.cs
/******************************************************************************** // Copyright (C) 2000-2006 Microsoft Corporation. All rights reserved. * ****************************************************************************/ #region Using directives using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Web; using System.Collections.Specialized; using System.Threading; using System.Web.Services; using System.Workflow.Runtime; using System.Workflow.Runtime.Hosting; using System.Security.Permissions; using System.Security.Principal; using System.Reflection; #endregion namespace System.Workflow.Activities { ////// Abstract WorkflowWebService Base class for all the Workflow's Web Service. /// public abstract class WorkflowWebService : WebService { Type workflowType; ////// Protected Constructor for the Workflow Web Service. /// /// protected WorkflowWebService(Type workflowType) { this.workflowType = workflowType; } protected Object[] Invoke(Type interfaceType, String methodName, bool isActivation, Object[] parameters) { Guid workflowInstanceId = GetWorkflowInstanceId(ref isActivation); WorkflowInstance wfInstance; EventQueueName key = new EventQueueName(interfaceType, methodName); MethodInfo mInfo = interfaceType.GetMethod(methodName); bool responseRequired = (mInfo.ReturnType != typeof(void)); if(!responseRequired) { foreach (ParameterInfo parameter in mInfo.GetParameters()) { if (parameter.ParameterType.IsByRef || parameter.IsOut) { responseRequired = true; break; } } } MethodMessage methodMessage = PrepareMessage(interfaceType, methodName, parameters, responseRequired); EventHandlerworkflowTerminationHandler = null; EventHandler workflowCompletedHandler = null; try { if (isActivation) { wfInstance = WorkflowRuntime.CreateWorkflow(this.workflowType, null, workflowInstanceId); SafeEnqueueItem(wfInstance, key, methodMessage); wfInstance.Start(); } else { wfInstance = WorkflowRuntime.GetWorkflow(workflowInstanceId); SafeEnqueueItem(wfInstance, key, methodMessage); } bool workflowTerminated = false; //Handler for workflow termination in b/w outstanding req-response. workflowTerminationHandler = delegate(Object sender, WorkflowTerminatedEventArgs e) { if (e.WorkflowInstance.InstanceId.Equals(workflowInstanceId)) { methodMessage.SendException(e.Exception); workflowTerminated = true; } }; workflowCompletedHandler = delegate(Object sender, WorkflowCompletedEventArgs e) { if (e.WorkflowInstance.InstanceId.Equals(workflowInstanceId)) { methodMessage.SendException(new ApplicationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_WorkflowCompleted))); } }; WorkflowRuntime.WorkflowTerminated += workflowTerminationHandler; WorkflowRuntime.WorkflowCompleted += workflowCompletedHandler; ManualWorkflowSchedulerService scheduler = WorkflowRuntime.GetService (); if (scheduler != null) { scheduler.RunWorkflow(wfInstance.InstanceId); } if (!responseRequired) { // no ret, out or ref return new Object[] { }; } IMethodResponseMessage response = methodMessage.WaitForResponseMessage(); if (response.Exception != null) { if(!workflowTerminated) throw response.Exception; else throw new ApplicationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_WorkflowTerminated), response.Exception); } if (response.OutArgs != null) return ((ArrayList)response.OutArgs).ToArray(); else return new Object[] { }; } finally { if(workflowTerminationHandler != null) WorkflowRuntime.WorkflowTerminated -= workflowTerminationHandler; if (workflowCompletedHandler != null) WorkflowRuntime.WorkflowCompleted -= workflowCompletedHandler; } } protected WorkflowRuntime WorkflowRuntime { get { if(HttpContext.Current != null) return WorkflowWebService.CurrentWorkflowRuntime; return null; } } #region Static Helpers private static Guid GetWorkflowInstanceId(ref bool isActivation) { Guid workflowInstanceId = Guid.Empty; Object instanceId = HttpContext.Current.Items["__WorkflowInstanceId__"]; if (instanceId == null && !isActivation) throw new InvalidOperationException(SR.GetString(SR.Error_NoInstanceInSession)); if (instanceId != null) { workflowInstanceId = (Guid)instanceId; Object isActivationContext = HttpContext.Current.Items["__IsActivationContext__"]; if (isActivationContext != null) isActivation = (bool)isActivationContext; else isActivation = false; } else if (isActivation) { workflowInstanceId = Guid.NewGuid(); HttpContext.Current.Items["__WorkflowInstanceId__"] = workflowInstanceId; } return workflowInstanceId; } private static MethodMessage PrepareMessage(Type interfaceType, String operation, object[] parameters, bool responseRequired) { // construct IMethodMessage object String securityIdentifier = null; IIdentity identity = System.Threading.Thread.CurrentPrincipal.Identity; WindowsIdentity windowsIdentity = identity as WindowsIdentity; if (windowsIdentity != null && windowsIdentity.User != null) securityIdentifier = windowsIdentity.User.Translate(typeof(NTAccount)).ToString(); else if (identity != null) securityIdentifier = identity.Name; MethodMessage msg = new MethodMessage(interfaceType, operation, parameters, securityIdentifier, responseRequired); return msg; } //Back - off logic for conflicting workflow load across workflow runtime boundaries. static void SafeEnqueueItem(WorkflowInstance instance, EventQueueName key, MethodMessage message) { while (true) //When Execution times out ASP.NET going to forcefully plung this request. { try { instance.EnqueueItem(key, message, null, null); return; } catch (WorkflowOwnershipException) { WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Warning, 0, String.Format(System.Globalization.CultureInfo.InvariantCulture, "Workflow Web Host Encountered Workflow Instance Ownership conflict for instanceid {0}.", instance.InstanceId)); //Back-off for 1/2 sec. Should we make this configurable? System.Threading.Thread.Sleep(500); continue; } } } #endregion #region Singleton WorkflowRuntime Accessor internal const string ConfigSectionName = "WorkflowRuntime"; static WorkflowRuntime wRuntime; static Object wRuntimeSync = new Object(); internal static WorkflowRuntime CurrentWorkflowRuntime { get { if (wRuntime == null) { lock (wRuntimeSync) { if (wRuntime == null) { WorkflowRuntime workflowRuntimeTemp = new WorkflowRuntime(ConfigSectionName); try { workflowRuntimeTemp.StartRuntime(); } catch { workflowRuntimeTemp.Dispose(); throw; } System.Threading.Thread.MemoryBarrier(); wRuntime = workflowRuntimeTemp; } } } return wRuntime; } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. /******************************************************************************** // Copyright (C) 2000-2006 Microsoft Corporation. All rights reserved. * ****************************************************************************/ #region Using directives using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Web; using System.Collections.Specialized; using System.Threading; using System.Web.Services; using System.Workflow.Runtime; using System.Workflow.Runtime.Hosting; using System.Security.Permissions; using System.Security.Principal; using System.Reflection; #endregion namespace System.Workflow.Activities { /// /// Abstract WorkflowWebService Base class for all the Workflow's Web Service. /// public abstract class WorkflowWebService : WebService { Type workflowType; ////// Protected Constructor for the Workflow Web Service. /// /// protected WorkflowWebService(Type workflowType) { this.workflowType = workflowType; } protected Object[] Invoke(Type interfaceType, String methodName, bool isActivation, Object[] parameters) { Guid workflowInstanceId = GetWorkflowInstanceId(ref isActivation); WorkflowInstance wfInstance; EventQueueName key = new EventQueueName(interfaceType, methodName); MethodInfo mInfo = interfaceType.GetMethod(methodName); bool responseRequired = (mInfo.ReturnType != typeof(void)); if(!responseRequired) { foreach (ParameterInfo parameter in mInfo.GetParameters()) { if (parameter.ParameterType.IsByRef || parameter.IsOut) { responseRequired = true; break; } } } MethodMessage methodMessage = PrepareMessage(interfaceType, methodName, parameters, responseRequired); EventHandlerworkflowTerminationHandler = null; EventHandler workflowCompletedHandler = null; try { if (isActivation) { wfInstance = WorkflowRuntime.CreateWorkflow(this.workflowType, null, workflowInstanceId); SafeEnqueueItem(wfInstance, key, methodMessage); wfInstance.Start(); } else { wfInstance = WorkflowRuntime.GetWorkflow(workflowInstanceId); SafeEnqueueItem(wfInstance, key, methodMessage); } bool workflowTerminated = false; //Handler for workflow termination in b/w outstanding req-response. workflowTerminationHandler = delegate(Object sender, WorkflowTerminatedEventArgs e) { if (e.WorkflowInstance.InstanceId.Equals(workflowInstanceId)) { methodMessage.SendException(e.Exception); workflowTerminated = true; } }; workflowCompletedHandler = delegate(Object sender, WorkflowCompletedEventArgs e) { if (e.WorkflowInstance.InstanceId.Equals(workflowInstanceId)) { methodMessage.SendException(new ApplicationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_WorkflowCompleted))); } }; WorkflowRuntime.WorkflowTerminated += workflowTerminationHandler; WorkflowRuntime.WorkflowCompleted += workflowCompletedHandler; ManualWorkflowSchedulerService scheduler = WorkflowRuntime.GetService (); if (scheduler != null) { scheduler.RunWorkflow(wfInstance.InstanceId); } if (!responseRequired) { // no ret, out or ref return new Object[] { }; } IMethodResponseMessage response = methodMessage.WaitForResponseMessage(); if (response.Exception != null) { if(!workflowTerminated) throw response.Exception; else throw new ApplicationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_WorkflowTerminated), response.Exception); } if (response.OutArgs != null) return ((ArrayList)response.OutArgs).ToArray(); else return new Object[] { }; } finally { if(workflowTerminationHandler != null) WorkflowRuntime.WorkflowTerminated -= workflowTerminationHandler; if (workflowCompletedHandler != null) WorkflowRuntime.WorkflowCompleted -= workflowCompletedHandler; } } protected WorkflowRuntime WorkflowRuntime { get { if(HttpContext.Current != null) return WorkflowWebService.CurrentWorkflowRuntime; return null; } } #region Static Helpers private static Guid GetWorkflowInstanceId(ref bool isActivation) { Guid workflowInstanceId = Guid.Empty; Object instanceId = HttpContext.Current.Items["__WorkflowInstanceId__"]; if (instanceId == null && !isActivation) throw new InvalidOperationException(SR.GetString(SR.Error_NoInstanceInSession)); if (instanceId != null) { workflowInstanceId = (Guid)instanceId; Object isActivationContext = HttpContext.Current.Items["__IsActivationContext__"]; if (isActivationContext != null) isActivation = (bool)isActivationContext; else isActivation = false; } else if (isActivation) { workflowInstanceId = Guid.NewGuid(); HttpContext.Current.Items["__WorkflowInstanceId__"] = workflowInstanceId; } return workflowInstanceId; } private static MethodMessage PrepareMessage(Type interfaceType, String operation, object[] parameters, bool responseRequired) { // construct IMethodMessage object String securityIdentifier = null; IIdentity identity = System.Threading.Thread.CurrentPrincipal.Identity; WindowsIdentity windowsIdentity = identity as WindowsIdentity; if (windowsIdentity != null && windowsIdentity.User != null) securityIdentifier = windowsIdentity.User.Translate(typeof(NTAccount)).ToString(); else if (identity != null) securityIdentifier = identity.Name; MethodMessage msg = new MethodMessage(interfaceType, operation, parameters, securityIdentifier, responseRequired); return msg; } //Back - off logic for conflicting workflow load across workflow runtime boundaries. static void SafeEnqueueItem(WorkflowInstance instance, EventQueueName key, MethodMessage message) { while (true) //When Execution times out ASP.NET going to forcefully plung this request. { try { instance.EnqueueItem(key, message, null, null); return; } catch (WorkflowOwnershipException) { WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Warning, 0, String.Format(System.Globalization.CultureInfo.InvariantCulture, "Workflow Web Host Encountered Workflow Instance Ownership conflict for instanceid {0}.", instance.InstanceId)); //Back-off for 1/2 sec. Should we make this configurable? System.Threading.Thread.Sleep(500); continue; } } } #endregion #region Singleton WorkflowRuntime Accessor internal const string ConfigSectionName = "WorkflowRuntime"; static WorkflowRuntime wRuntime; static Object wRuntimeSync = new Object(); internal static WorkflowRuntime CurrentWorkflowRuntime { get { if (wRuntime == null) { lock (wRuntimeSync) { if (wRuntime == null) { WorkflowRuntime workflowRuntimeTemp = new WorkflowRuntime(ConfigSectionName); try { workflowRuntimeTemp.StartRuntime(); } catch { workflowRuntimeTemp.Dispose(); throw; } System.Threading.Thread.MemoryBarrier(); wRuntime = workflowRuntimeTemp; } } } return wRuntime; } } #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
- ZipIOCentralDirectoryFileHeader.cs
- ImageAutomationPeer.cs
- TagNameToTypeMapper.cs
- ISFClipboardData.cs
- XPathNodeHelper.cs
- DerivedKeySecurityTokenStub.cs
- XmlSchemaInclude.cs
- WrappedKeySecurityToken.cs
- ToolBarTray.cs
- NullEntityWrapper.cs
- DynamicILGenerator.cs
- AssemblyCache.cs
- SingleConverter.cs
- DbgUtil.cs
- DockPanel.cs
- OdbcEnvironmentHandle.cs
- SoapInteropTypes.cs
- WebBrowserUriTypeConverter.cs
- FormViewUpdatedEventArgs.cs
- BigInt.cs
- FileLogRecordHeader.cs
- ReadOnlyHierarchicalDataSourceView.cs
- RedirectionProxy.cs
- DataTableReader.cs
- RegistryPermission.cs
- DataGridViewControlCollection.cs
- SerializationAttributes.cs
- ISO2022Encoding.cs
- CatalogZone.cs
- NetworkAddressChange.cs
- _ShellExpression.cs
- ToolStripDropDown.cs
- Overlapped.cs
- BaseDataList.cs
- ThemeDictionaryExtension.cs
- VarRefManager.cs
- DropShadowEffect.cs
- Soap.cs
- LayoutInformation.cs
- OperationInvokerTrace.cs
- MouseDevice.cs
- InputLanguageProfileNotifySink.cs
- BadImageFormatException.cs
- StorageRoot.cs
- PeerTransportCredentialType.cs
- DefaultPropertyAttribute.cs
- DefaultEvaluationContext.cs
- DataTemplateSelector.cs
- ToolBarPanel.cs
- ToolStripMenuItemDesigner.cs
- MiniModule.cs
- ReaderOutput.cs
- EntityTypeEmitter.cs
- DataGridTextBoxColumn.cs
- ExpressionParser.cs
- CodeGenerator.cs
- SqlMethods.cs
- SuppressMessageAttribute.cs
- Codec.cs
- XmlTextReader.cs
- Point3DCollectionConverter.cs
- ChangeDirector.cs
- SystemEvents.cs
- ToolStripItemCollection.cs
- TemplateKey.cs
- WmpBitmapEncoder.cs
- FactoryGenerator.cs
- TimeIntervalCollection.cs
- MobileListItem.cs
- ActivityInstanceMap.cs
- ToolBar.cs
- sqlser.cs
- _ListenerAsyncResult.cs
- Menu.cs
- VisualStyleTypesAndProperties.cs
- WebPartChrome.cs
- Triangle.cs
- SecurityKeyIdentifierClause.cs
- TreeNodeBinding.cs
- GuidTagList.cs
- SynthesizerStateChangedEventArgs.cs
- BmpBitmapDecoder.cs
- CategoryNameCollection.cs
- LogEntryHeaderSerializer.cs
- WebResourceAttribute.cs
- ColorBlend.cs
- GroupStyle.cs
- ObjectItemLoadingSessionData.cs
- SpecularMaterial.cs
- CharacterMetricsDictionary.cs
- DropShadowBitmapEffect.cs
- PrincipalPermission.cs
- DesignerObject.cs
- TileBrush.cs
- CollectionBase.cs
- CollaborationHelperFunctions.cs
- Cursor.cs
- SQLDecimal.cs
- _ShellExpression.cs
- DocumentSequence.cs