⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 callerthreadcontext.cs

📁 线程池实例,1.1版本,用于代替.net自带线程池
💻 CS
字号:
using System;
using System.Diagnostics;
using System.Threading;
using System.Reflection;
using System.Web;
using System.Runtime.Remoting.Messaging;


namespace Amib.Threading
{
	#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 MethodInfo getLogicalCallContextMethodInfo =
			typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);

		private static 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);
			else // Use the default "HttpContext" slot name
				return "HttpContext";
		}

		#endregion

		#region Private fields

		private HttpContext _httpContext = null;
		private LogicalCallContext _callContext = null;

		#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)
			{
				CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
			}
		}
	}

	#endregion

}


/*
// Ami Bar
// amibar@gmail.com

using System;
using System.Threading;
using System.Globalization;
using System.Security.Principal;
using System.Reflection;
using System.Runtime.Remoting.Contexts;

namespace Amib.Threading.Internal
{
	#region CallerThreadContext class

	/// <summary>
	/// This class stores the caller thread context in order to restore
	/// it when the work item is executed in the context of the thread 
	/// from the pool.
	/// Note that we can't store the thread's CompressedStack, because 
	/// it throws a security exception
	/// </summary>
	public class CallerThreadContext
	{
		private CultureInfo _culture = null;
		private CultureInfo _cultureUI = null;
		private IPrincipal _principal;
		private System.Runtime.Remoting.Contexts.Context _context;

		private static FieldInfo _fieldInfo = GetFieldInfo();

		private static FieldInfo GetFieldInfo()
		{
			Type threadType = typeof(Thread);
			return threadType.GetField(
				"m_Context",
				BindingFlags.Instance | BindingFlags.NonPublic);
		}

		/// <summary>
		/// Constructor
		/// </summary>
		private CallerThreadContext()
		{
		}

		/// <summary>
		/// Captures the current thread context
		/// </summary>
		/// <returns></returns>
		public static CallerThreadContext Capture()
		{
			CallerThreadContext callerThreadContext = new CallerThreadContext();

			Thread thread = Thread.CurrentThread;
			callerThreadContext._culture = thread.CurrentCulture;
			callerThreadContext._cultureUI = thread.CurrentUICulture;
			callerThreadContext._principal = Thread.CurrentPrincipal;
			callerThreadContext._context = Thread.CurrentContext;
			return callerThreadContext;
		}

		/// <summary>
		/// Applies the thread context stored earlier
		/// </summary>
		/// <param name="callerThreadContext"></param>
		public static void Apply(CallerThreadContext callerThreadContext)
		{
			Thread thread = Thread.CurrentThread;
			thread.CurrentCulture = callerThreadContext._culture;
			thread.CurrentUICulture = callerThreadContext._cultureUI;
			Thread.CurrentPrincipal = callerThreadContext._principal;

			// Uncomment the following block to enable the Thread.CurrentThread
/*
			if (null != _fieldInfo)
			{
				_fieldInfo.SetValue(
					Thread.CurrentThread, 
					callerThreadContext._context);
			}
* /			
		}
	}

	#endregion
}
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -