AmbientEnvironment.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / RunTime / AmbientEnvironment.cs / 1305376 / AmbientEnvironment.cs

                            #region Imports 

using System;
using System.Xml;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.Specialized; 
using System.Threading; 
using System.Transactions;
using System.Reflection; 
using System.Workflow.ComponentModel;
using System.Workflow.Runtime.Hosting;
using System.Diagnostics;
 
#endregion
 
namespace System.Workflow.Runtime 
{
    #region Class AmbientEnvironment 

    internal abstract class AmbientEnvironment : IDisposable
    {
        ///  
        /// Indicates that the value of a static field is unique for each thread
        /// CLR Perf suggests using this attribute over the slot approach. 
        ///  
        [ThreadStatic()]
        static EnvWrapper threadData; 

        readonly object _prevEnv;
        readonly int _prevRC;
 
        protected AmbientEnvironment(object env)
        { 
            if (threadData == null) 
            {
                //Setting TLS for the first time 
                threadData = new EnvWrapper();
            }

 			threadData.Push(env, out _prevEnv, out _prevRC); 
        }
 
        void IDisposable.Dispose() 
        {
            Debug.Assert(null != threadData); 
            threadData.Pop(_prevEnv, _prevRC);
            if (_prevRC == 0)
            {
                threadData = null; 
            }
        } 
 
        internal static object Retrieve()
        { 
            if (threadData != null)
                return threadData.Retrieve();
            else
                return null; 
        }
 
        private class EnvWrapper 
        {
            int _rc; 

            object _currEnv;

            internal void Push(object env, out object prevEnv, out int prevRc) 
            {
                Debug.Assert(_rc >= 0); 
                prevEnv = _currEnv; 
                prevRc = _rc;
                _rc++; 
                _currEnv = env;
            }

            internal void Pop(object prevEnv, int prevRC) 
            {
                Debug.Assert(_rc > 0); 
                _rc--; 
                _currEnv = prevEnv;
                if (_rc != prevRC) 
                {
                    Debug.Assert(false);
                   //
                } 
            }
 
            internal object Retrieve() 
            {
                Debug.Assert(_rc > 0); 
                return _currEnv;
            }
        }
    } 

    #endregion 
 
    #region Class ServiceEnvironment
 
    // This class presents the transactional view of a WF instance:
    // mainly the current batch in transaction, and NOT the runtime view
    // of currently executing activity.
    internal sealed class ServiceEnvironment : AmbientEnvironment 
    {
        internal static readonly Guid debuggerThreadGuid = new Guid("54D747AE-5CC6-4171-95C8-0A8C40443915"); 
 
        internal ServiceEnvironment(Activity currentActivity)
            : base(currentActivity) 
        {
            GC.SuppressFinalize(this);
        }
 
        internal static IWorkBatch WorkBatch
        { 
            get 
            {
				Activity currentActivity = ServiceEnvironment.CurrentActivity; 
				if (currentActivity == null)
					return null;
                else
 					return (IWorkBatch)currentActivity.GetValue(WorkflowExecutor.TransientBatchProperty); 
            }
        } 
 
        internal static Guid WorkflowInstanceId
        { 
            get
            {
				Activity currentActivity = ServiceEnvironment.CurrentActivity;
 				if (currentActivity == null) 
                    return Guid.Empty;
 
 				return ((Guid)ContextActivityUtils.RootContextActivity(currentActivity).GetValue(WorkflowExecutor.WorkflowInstanceIdProperty)); 
            }
        } 

        internal static WorkflowQueuingService QueuingService
        {
            get 
            {
                Activity currentActivity = ServiceEnvironment.CurrentActivity; 
 
				// fetch workflow executor
 				IWorkflowCoreRuntime workflowExecutor = null; 
				if(currentActivity != null)
					workflowExecutor = ContextActivityUtils.RetrieveWorkflowExecutor(currentActivity);

                while (currentActivity != null) 
                {
					if (currentActivity == workflowExecutor.CurrentAtomicActivity) 
                    { 
                        TransactionalProperties transactionalProperties = (TransactionalProperties)currentActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty);
                        if (transactionalProperties != null) 
                        {
                            if (transactionalProperties.LocalQueuingService != null)
                            {
                                WorkflowQueuingService queuingService = transactionalProperties.LocalQueuingService; 
                                return queuingService; // return local queuing service
                            } 
                        } 
                    }
                    currentActivity = currentActivity.Parent; 
                }
                return null;
            }
        } 

        // DO NOT change this to internal/public 
        // Technically we only want to store the Batch in the TLS, 
        // but because we also want the queueing service and instId,
        // we are storing the object encapsulating all the info. 
        // The service environment only represents the transactional view:
        // the current batch; and not the current executing view:
        // e.g. some caller/caller, send/receive scenarios where
        // we want the current batch to be the caller's so this activity 
        // does not reflect the executing activity (the callee).
        private static Activity CurrentActivity 
        { 
            get
            { 
                object o = AmbientEnvironment.Retrieve();
                return o as Activity;
            }
        } 

        internal static bool IsInServiceThread(Guid instanceId) 
        { 
            System.Diagnostics.Debug.Assert(instanceId != Guid.Empty, "IsInServiceThread expects valid guid.");
            if (WorkflowInstanceId == instanceId) 
                return true;

            return DebuggerThreadMarker.IsInDebuggerThread();
        } 
    }
 
    #endregion 

    #region Class DebuggerThreadMarker 

    internal class DebuggerThreadMarker : AmbientEnvironment
    {
        public DebuggerThreadMarker(): base(new object()) 
        {
        } 
 
        internal static bool IsInDebuggerThread()
        { 
            return AmbientEnvironment.Retrieve() != null;
        }
    }
 
    #endregion
 
    #region Class RuntimeEnvironment 

    internal class RuntimeEnvironment : IDisposable 
    {
        [ThreadStatic()]
        static WorkflowRuntime workflowRuntime;
 
        public RuntimeEnvironment(WorkflowRuntime runtime)
        { 
            workflowRuntime = runtime; 
        }
 
        internal static WorkflowRuntime CurrentRuntime
        {
            get
            { 
                return RuntimeEnvironment.workflowRuntime;
            } 
        } 
        void IDisposable.Dispose()
        { 
            workflowRuntime = null;
        }
    }
 
    #endregion
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK