123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- #if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
- using System;
- using System.Diagnostics;
- using System.Threading;
- using System.Reflection;
- using System.Web;
- using System.Runtime.Remoting.Messaging;
- namespace Amib.Threading.Internal
- {
- #region CallerThreadContext class
- /// <summary>
- /// This class stores the caller call context in order to restore
- /// it when the work item is executed in the thread pool environment.
- /// </summary>
- internal class CallerThreadContext
- {
- #region Prepare reflection information
- // Cached type information.
- private static readonly MethodInfo getLogicalCallContextMethodInfo =
- typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
- private static readonly MethodInfo setLogicalCallContextMethodInfo =
- typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
- private static string HttpContextSlotName = GetHttpContextSlotName();
- private static string GetHttpContextSlotName()
- {
- FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic);
- if (fi != null)
- {
- return (string) fi.GetValue(null);
- }
- return "HttpContext";
- }
- #endregion
- #region Private fields
- private HttpContext _httpContext;
- private LogicalCallContext _callContext;
- #endregion
- /// <summary>
- /// Constructor
- /// </summary>
- private CallerThreadContext()
- {
- }
- public bool CapturedCallContext
- {
- get
- {
- return (null != _callContext);
- }
- }
- public bool CapturedHttpContext
- {
- get
- {
- return (null != _httpContext);
- }
- }
- /// <summary>
- /// Captures the current thread context
- /// </summary>
- /// <returns></returns>
- public static CallerThreadContext Capture(
- bool captureCallContext,
- bool captureHttpContext)
- {
- Debug.Assert(captureCallContext || captureHttpContext);
- CallerThreadContext callerThreadContext = new CallerThreadContext();
- // TODO: In NET 2.0, redo using the new feature of ExecutionContext class - Capture()
- // Capture Call Context
- if(captureCallContext && (getLogicalCallContextMethodInfo != null))
- {
- callerThreadContext._callContext = (LogicalCallContext)getLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, null);
- if (callerThreadContext._callContext != null)
- {
- callerThreadContext._callContext = (LogicalCallContext)callerThreadContext._callContext.Clone();
- }
- }
- // Capture httpContext
- if (captureHttpContext && (null != HttpContext.Current))
- {
- callerThreadContext._httpContext = HttpContext.Current;
- }
- return callerThreadContext;
- }
- /// <summary>
- /// Applies the thread context stored earlier
- /// </summary>
- /// <param name="callerThreadContext"></param>
- public static void Apply(CallerThreadContext callerThreadContext)
- {
- if (null == callerThreadContext)
- {
- throw new ArgumentNullException("callerThreadContext");
- }
- // Todo: In NET 2.0, redo using the new feature of ExecutionContext class - Run()
- // Restore call context
- if ((callerThreadContext._callContext != null) && (setLogicalCallContextMethodInfo != null))
- {
- setLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, new object[] { callerThreadContext._callContext });
- }
- // Restore HttpContext
- if (callerThreadContext._httpContext != null)
- {
- HttpContext.Current = callerThreadContext._httpContext;
- //CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
- }
- }
- }
- #endregion
- }
- #endif
|