private void RunInBackground(Action<string> action) { var threadContext = new LogicalThreadContext(); var value = threadContext.Get<string>(ItemKey); action(value); }
/// <summary> /// Creates the message converter given its name in the application context. /// </summary> /// <param name="messageConverterObjectName">Name of the message converter object.</param> /// <returns> /// A IMessageConverter instance configured via the application context /// </returns> public IMessageConverter CreateMessageConverter(string messageConverterObjectName) { AssertUtils.ArgumentHasText(messageConverterObjectName, "MessgaeFormatterObjectName"); IDictionary converters = LogicalThreadContext.GetData(CONVERTER_DICTIONARY_SLOTNAME) as IDictionary; if (converters == null) { converters = new Hashtable(); LogicalThreadContext.SetData(CONVERTER_DICTIONARY_SLOTNAME, converters); } if (!converters.Contains(messageConverterObjectName)) { IMessageConverter mc = (IMessageConverter) applicationContext.GetObject(messageConverterObjectName, typeof(IMessageConverter)); if (applicationContext.ObjectFactory.GetObjectDefinition(messageConverterObjectName).IsSingleton) { log.Warn("MessageConverter with name = [" + messageConverterObjectName + "] should be declared with singleton=false. Using Clone() to create independent instance for thread local storage"); converters.Add(messageConverterObjectName, mc.Clone()); } else { converters.Add(messageConverterObjectName, mc); } } return(converters[messageConverterObjectName] as IMessageConverter); }
/// <summary> /// For webapplications always /// <ul> /// <li>convert IResources using the current context.</li> /// <li>use "web" as default resource protocol</li> /// <li>use <see cref="HybridContextStorage"/> as default threading storage</li> /// </ul> /// </summary> static WebSupportModule() { s_log = LogManager.GetLogger(typeof(WebSupportModule)); #if NET_2_0 // required to enable accessing HttpContext.Request during IHttpModule.Init() in integrated mode ContextHideRequestResponse = null; try { fiHideRequestResponse = typeof(HttpContext).GetField("HideRequestResponse", BindingFlags.Instance | BindingFlags.NonPublic); // fiHideRequestResponse.SetValue(HttpContext.Current, false); ContextHideRequestResponse = (fiHideRequestResponse != null)?new SafeField(fiHideRequestResponse):null; } catch (SecurityException sec) { s_log.Warn(string.Format("failed reflecting field HttpContext.HideRequestResponse due to security restrictions {0}", sec)); } #endif // register additional resource handler ResourceHandlerRegistry.RegisterResourceHandler(WebUtils.DEFAULT_RESOURCE_PROTOCOL, typeof(WebResource)); // replace default IResource converter TypeConverterRegistry.RegisterConverter(typeof(IResource), new ResourceConverter( new ConfigurableResourceLoader(WebUtils.DEFAULT_RESOURCE_PROTOCOL))); // default to hybrid thread storage implementation LogicalThreadContext.SetStorage(new HybridContextStorage()); s_log.Debug("Set default resource protocol to 'web' and installed HttpContext-aware HybridContextStorage"); }
/// <summary> /// Bind the given resource for teh given key to the current thread /// </summary> /// <param name="key">key to bind the value to</param> /// <param name="value">value to bind</param> public static void BindResource(Object key, Object value) { AssertUtils.ArgumentNotNull(key, "Key value for thread local storage of transactional resources must not be null"); AssertUtils.ArgumentNotNull(value, "Transactional resource to bind to thread local storage must not be null"); IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary; //Set thread local resource storage if not found if (resources == null) { resources = new Hashtable(); LogicalThreadContext.SetData(resourcesDataSlotName, resources); } if (resources.Contains(key)) { throw new InvalidOperationException("Already value [" + resources[key] + "] for key [" + key + "] bound to thread [" + SystemUtils.ThreadId + "]"); } resources.Add(key, value); if (LOG.IsDebugEnabled) { LOG.Debug("Bound value [" + Describe(value) + "] for key [" + Describe(key) + "] to thread [" + SystemUtils.ThreadId + "]"); } }
public void FallbackToDefault() { IDbProvider provider1 = DbProviderFactory.GetDbProvider("System.Data.SqlClient"); provider1.ConnectionString = "connString1"; IDbProvider provider2 = DbProviderFactory.GetDbProvider("System.Data.SqlClient"); provider2.ConnectionString = "connString2"; MultiDelegatingDbProvider multiDbProvider = new MultiDelegatingDbProvider(); IDictionary targetDbProviders = new Hashtable(); targetDbProviders.Add("db1", provider1); targetDbProviders.Add("db2", provider2); multiDbProvider.DefaultDbProvider = provider1; multiDbProvider.TargetDbProviders = targetDbProviders; multiDbProvider.AfterPropertiesSet(); MultiDelegatingDbProvider.CurrentDbProviderName = "db314"; try { Assert.AreEqual("connString1", multiDbProvider.ConnectionString); } finally { LogicalThreadContext.FreeNamedDataSlot(MultiDelegatingDbProvider.CURRENT_DBPROVIDER_SLOTNAME); } }
public void NoDefaultProvided() { IDbProvider provider = DbProviderFactory.GetDbProvider("System.Data.SqlClient"); provider.ConnectionString = "connString1"; MultiDelegatingDbProvider multiDbProvider = new MultiDelegatingDbProvider(); IDictionary targetDbProviders = new Hashtable(); targetDbProviders.Add("db1", provider); multiDbProvider.TargetDbProviders = targetDbProviders; multiDbProvider.AfterPropertiesSet(); try { Assert.AreEqual("connString1", multiDbProvider.ConnectionString); Assert.Fail("InvalidDataAccessApiUsageException should have been thrown"); } catch (InvalidDataAccessApiUsageException exception) { Assert.AreEqual("No provider name found in thread local storage. Consider setting the property DefaultDbProvider to fallback to a default value.", exception.Message); } finally { LogicalThreadContext.FreeNamedDataSlot(MultiDelegatingDbProvider.CURRENT_DBPROVIDER_SLOTNAME); } }
/// <summary> /// Unbind a resource for the given key from the current thread /// </summary> /// <param name="key">key to check</param> /// <returns>the previously bound value</returns> /// <exception cref="InvalidOperationException">if there is no value bound to the thread</exception> public static object UnbindResource(Object key) { AssertUtils.ArgumentNotNull(key, "Key must not be null"); IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary; if (resources == null || !resources.Contains(key)) { throw new InvalidOperationException("No value for key [" + key + "] bound to thread [" + SystemUtils.ThreadId + "]"); } Object val = resources[key]; resources.Remove(key); if (resources.Count == 0) { LogicalThreadContext.FreeNamedDataSlot(resourcesDataSlotName); } if (LOG.IsDebugEnabled) { LOG.Debug("Removed value [" + Describe(val) + "] for key [" + Describe(key) + "] from thread [" + SystemUtils.ThreadId + "]"); } return(val); }
/// <summary> /// Configures the current IHttpHandler as specified by <see cref="Spring.Web.Support.PageHandlerFactory" />. If the /// <see cref="Spring.Web.Support.PageHandlerFactory" /> is not executed for the current request and an instance of /// <see cref="Page" /> is served revalidate if the instance should be configured. /// </summary> private void OnConfigureHandler(object sender, EventArgs e) { HttpApplication app = (HttpApplication)sender; HandlerConfigurationMetaData hCfg = (HandlerConfigurationMetaData)LogicalThreadContext.GetData(CURRENTHANDLER_OBJECTDEFINITION); if (hCfg != null) { // app.Context.Handler = // TODO: check, if this makes sense (EE) ConfigureHandlerNow(app.Context.Handler, hCfg.ApplicationContext, hCfg.ObjectDefinitionName, hCfg.IsContainerManaged); } else { Page page = app.Context.Handler as Page; if (!IsPageWithRouteHandler(page)) { return; } // In case of Routing pages are not handled by the PageHandlerFactory therefore no HandlerConfigurationMetaData // is set. IConfigurableApplicationContext applicationContext = (IConfigurableApplicationContext)WebApplicationContext.Current; string normalizedVirtualPath = WebUtils.GetNormalizedVirtualPath(page.AppRelativeVirtualPath); ControlInterceptor.EnsureControlIntercepted(applicationContext, page); ConfigureHandlerNow(page, applicationContext, normalizedVirtualPath, true); } }
public void NoMatchingProviderDefinedInThreadLocalStorage() { IDbProvider provider = DbProviderFactory.GetDbProvider("System.Data.SqlClient"); provider.ConnectionString = "connString1"; MultiDelegatingDbProvider multiDbProvider = new MultiDelegatingDbProvider(); IDictionary targetDbProviders = new Hashtable(); targetDbProviders.Add("db1", provider); multiDbProvider.TargetDbProviders = targetDbProviders; multiDbProvider.AfterPropertiesSet(); try { MultiDelegatingDbProvider.CurrentDbProviderName = "db2"; Assert.AreEqual("connString1", multiDbProvider.ConnectionString); Assert.Fail("InvalidDataAccessApiUsageException should have been thrown"); } catch (InvalidDataAccessApiUsageException exception) { Assert.AreEqual("'db2' was not under the thread local key 'dbProviderName' and no default IDbProvider was set.", exception.Message); } finally { LogicalThreadContext.FreeNamedDataSlot(MultiDelegatingDbProvider.CURRENT_DBPROVIDER_SLOTNAME); } }
/// <summary> /// Gets the target provider based on the thread local name "dbProviderName" /// </summary> /// <returns>The corresonding IDbProvider.</returns> protected virtual IDbProvider GetTargetProvider() { string dbProviderName = (string)LogicalThreadContext.GetData(CURRENT_DBPROVIDER_SLOTNAME); if (dbProviderName != null && targetDbProviders.Contains(dbProviderName)) { return((IDbProvider)targetDbProviders[dbProviderName]); } //Fall back to default if available if (defaultDbProvider != null) { if (LOG.IsDebugEnabled) { LOG.Debug("No DbProvider defined in thread local storage, falling back to use DefaultDbProvider."); } return(defaultDbProvider); } if (dbProviderName == null) { throw new InvalidDataAccessApiUsageException( "No provider name found in thread local storage. Consider setting the property DefaultDbProvider to fallback to a default value."); } throw new InvalidDataAccessApiUsageException("'" + dbProviderName + "'" + " was not under the thread local key 'dbProviderName' and no default IDbProvider was set."); }
/// <summary> /// Binds this /// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo"/> /// instance to the thread local storage variable for the current thread and /// backs up the existing /// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo"/> /// object for the current thread. /// </summary> public void BindToThread() { // Expose current TransactionStatus, preserving any existing TransactionStatus // for restoration after this transaction is complete. TransactionInfo currentTransactionInfo = LogicalThreadContext.GetData(CURRENT_TRANSACTIONINFO_SLOTNAME) as TransactionInfo; _oldTransactionInfo = currentTransactionInfo; LogicalThreadContext.SetData(CURRENT_TRANSACTIONINFO_SLOTNAME, this); }
/// <summary> /// Return if deferred close is active for the current thread /// and the given SessionFactory.</summary> /// <param name="sessionFactory">The session factory.</param> /// <returns> /// <c>true</c> if [is deferred close active] [the specified session factory]; otherwise, <c>false</c>. /// </returns> /// <exception cref="ArgumentNullException">If SessionFactory argument is null.</exception> public static bool IsDeferredCloseActive(ISessionFactory sessionFactory) { if (sessionFactory == null) { throw new ArgumentNullException("sessionFactory", "No SessionFactory specified"); } IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary; return(holderDictionary != null && holderDictionary.Contains(sessionFactory)); }
/// <summary> /// 获取线程的WarehouseId /// </summary> /// <returns>get the warehouseId bounded to current thread.</returns> public static string GetCurrentThreadWarehouseId() { object warehouseId = LogicalThreadContext.GetData(CURRENT_WAREHOUSE_ID); if (warehouseId == null) { return(string.Empty); } return(warehouseId.ToString()); }
///<summary> /// Configures the current IHttpHandler as specified by <see cref="Spring.Web.Support.PageHandlerFactory"/>. ///</summary> private void OnConfigureHandler(object sender, EventArgs e) { HandlerConfigurationMetaData hCfg = (HandlerConfigurationMetaData)LogicalThreadContext.GetData(CURRENTHANDLER_OBJECTDEFINITION); if (hCfg != null) { HttpApplication app = (HttpApplication)sender; // app.Context.Handler = // TODO: check, if this makes sense (EE) ConfigureHandlerNow(app.Context.Handler, hCfg.ApplicationContext, hCfg.ObjectDefinitionName, hCfg.IsContainerManaged); } }
protected override void Given() { _context = new LogicalThreadContext(); _context.Set("firstItem", "foo"); _context.Set("secondItem", "fee"); _context.Set("thirdItem", "foe"); _context.Set("complexSerializableItem", new Serializable { Foo = "bar" }); }
/// <summary> /// Sets a flag, whether this scope is in "open" state on the current logical thread. /// </summary> private void SetOpen(bool isOpen) { if (isOpen) { LogicalThreadContext.SetData(ISOPEN_KEY, ISOPEN_KEY); } else { LogicalThreadContext.FreeNamedDataSlot(ISOPEN_KEY); } }
/// <summary> /// Gets/Sets a flag, whether this scope manages it's own session for the current logical thread or not. /// </summary> /// <value><c>false</c> if session is managed by this module. <c>false</c> otherwise</value> private void SetParticipating(bool participating) { if (participating) { LogicalThreadContext.SetData(PARTICIPATE_KEY, PARTICIPATE_KEY); } else { LogicalThreadContext.FreeNamedDataSlot(PARTICIPATE_KEY); } }
/// <summary> /// Deactivate transaction synchronization for the current thread. /// </summary> /// <remarks> /// Called by transaction manager on transaction cleanup. /// </remarks> /// <exception cref="System.InvalidOperationException"> /// If synchronization is not active. /// </exception> public static void ClearSynchronization() { if (!SynchronizationActive) { throw new InvalidOperationException("Cannot deactivate transaction synchronization - not active"); } if (LOG.IsDebugEnabled) { LOG.Debug("Clearing transaction synchronization"); } LogicalThreadContext.FreeNamedDataSlot(syncsDataSlotName); }
/// <summary> /// 把当前UnitOfWork压入当前线程的事务线中 /// 如果当前线程中不存在事务栈,则创建事务栈,并把事务栈放入当前线程 /// 否则从当前线程中取出栈,并把当前UnitOfWork压入栈中 /// </summary> public static void Push(IUnitOfWork unitOfWork) { if (ThreadBoundUnitOfWorkStack == null) { var stack = new Stack <IUnitOfWork>(); stack.Push(unitOfWork); LogicalThreadContext.SetData(UnitOfWorkStack, stack); } else { ThreadBoundUnitOfWorkStack.Push(unitOfWork); } }
/// <summary> /// Process the xml file in the given location, and schedule all of the /// jobs defined within it. /// </summary> /// <param name="fileName">Name of the file.</param> /// <param name="systemId">The system id.</param> /// <param name="sched">The sched.</param> public virtual void ProcessFileAndScheduleJobs(string fileName, string systemId, IScheduler sched) { LogicalThreadContext.SetData(ThreadLocalKeyScheduler, sched); try { ProcessFile(fileName, systemId); ExecutePreProcessCommands(sched); ScheduleJobs(sched); } finally { LogicalThreadContext.FreeNamedDataSlot(ThreadLocalKeyScheduler); } }
/// <summary> /// Process the xml file in the given location, and schedule all of the /// jobs defined within it. /// </summary> /// <param name="fileName">Name of the file.</param> /// <param name="systemId">The system id.</param> /// <param name="sched">The sched.</param> public virtual async Task ProcessFileAndScheduleJobs(string fileName, string systemId, IScheduler sched) { LogicalThreadContext.SetData(ThreadLocalKeyScheduler, sched); try { await ProcessFile(fileName, systemId).ConfigureAwait(false); await ExecutePreProcessCommands(sched).ConfigureAwait(false); await ScheduleJobs(sched).ConfigureAwait(false); } finally { LogicalThreadContext.FreeNamedDataSlot(ThreadLocalKeyScheduler); } }
/// <summary> /// Activate transaction synchronization for the current thread. /// </summary> /// <remarks> /// Called by transaction manager at the beginning of a transaction. /// </remarks> /// <exception cref="System.InvalidOperationException"> /// If synchronization is already active. /// </exception> public static void InitSynchronization() { if (SynchronizationActive) { throw new InvalidOperationException("Cannot activate transaction synchronization - already active"); } if (LOG.IsDebugEnabled) { LOG.Debug("Initializing transaction synchronization"); } ArrayList syncs = new ArrayList(); LogicalThreadContext.SetData(syncsDataSlotName, syncs); }
/// <summary> /// Returns a new connection object to communicate with the database. /// Determine if there are currently thread-bound credentials, using them if /// available, falling back to the statically specified username and password /// (i.e. values of the properties 'Username' and 'Password') otherwise. /// The username and password will be concatenated on the connection string /// using string in the Separator property /// </summary> /// <returns>A new <see cref="IDbConnection"/></returns> public override IDbConnection CreateConnection() { string user = LogicalThreadContext.GetData(USERNAME) as string; string pass = LogicalThreadContext.GetData(PASSWORD) as string; if (user != null && pass != null) { return(DoCreateConnection(user, pass)); } else { return(DoCreateConnection(username, password)); } }
/// <summary> /// Process the xml file in the given location, and schedule all of the /// jobs defined within it. /// </summary> /// <param name="fileName">Name of the file.</param> /// <param name="systemId">The system id.</param> /// <param name="sched">The sched.</param> /// <param name="overwriteExistingJobs">if set to <c>true</c> [over write existing jobs].</param> public virtual void ProcessFileAndScheduleJobs(string fileName, string systemId, IScheduler sched, bool overwriteExistingJobs) { LogicalThreadContext.SetData(ThreadLocalKeyScheduler, sched); try { ProcessFile(fileName, systemId); ScheduleJobs(ScheduledJobs, sched, overwriteExistingJobs); } finally { LogicalThreadContext.FreeNamedDataSlot(ThreadLocalKeyScheduler); } }
/// <summary> /// 从当前线程的UnitOfWork栈中移除顶部的对象 /// 如果当前线程中不存在事务栈,则返回<see langword="null"></see> /// </summary> /// <returns>The UnitOfWork which at the top of Stack in the current thread.</returns> public static IUnitOfWork Pop() { if (ThreadBoundUnitOfWorkStack == null) { return(null); } IUnitOfWork unitOfWork = ThreadBoundUnitOfWorkStack.Pop(); if (ThreadBoundUnitOfWorkStack.Count == 0) { LogicalThreadContext.FreeNamedDataSlot(UnitOfWorkStack); } return(unitOfWork); }
/// <summary> ///Initialize deferred close for the current thread and the given SessionFactory. /// Sessions will not be actually closed on close calls then, but rather at a /// processDeferredClose call at a finishing point (like request completion). /// </summary> /// <param name="sessionFactory">The session factory.</param> public static void InitDeferredClose(ISessionFactory sessionFactory) { AssertUtils.ArgumentNotNull(sessionFactory, "No SessionFactory specified"); log.Debug("Initializing deferred close of Hibernate Sessions"); IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary; if (holderDictionary == null) { holderDictionary = new Hashtable(); LogicalThreadContext.SetData(DeferredCloseHolderDataSlotName, holderDictionary); } holderDictionary.Add(sessionFactory, new ListSet()); }
/// <summary> /// Process the xml file in the given location, and schedule all of the /// jobs defined within it. /// </summary> /// <param name="stream">stream to read XML data from.</param> /// <param name="sched">The sched.</param> public virtual void ProcessStreamAndScheduleJobs(Stream stream, IScheduler sched) { LogicalThreadContext.SetData(ThreadLocalKeyScheduler, sched); try { using (var sr = new StreamReader(stream)) { ProcessInternal(sr.ReadToEnd()); } ExecutePreProcessCommands(sched); ScheduleJobs(sched); } finally { LogicalThreadContext.FreeNamedDataSlot(ThreadLocalKeyScheduler); } }
/// <summary> /// Process the xml file in the given location, and schedule all of the /// jobs defined within it. /// </summary> /// <param name="stream">stream to read XML data from.</param> /// <param name="sched">The sched.</param> public virtual async Task ProcessStreamAndScheduleJobs(Stream stream, IScheduler sched) { LogicalThreadContext.SetData(ThreadLocalKeyScheduler, sched); try { using (var sr = new StreamReader(stream)) { ProcessInternal(await sr.ReadToEndAsync().ConfigureAwait(false)); } await ExecutePreProcessCommands(sched).ConfigureAwait(false); await ScheduleJobs(sched).ConfigureAwait(false); } finally { LogicalThreadContext.FreeNamedDataSlot(ThreadLocalKeyScheduler); } }
/// <summary> /// Close the given Session or register it for deferred close. /// </summary> /// <param name="session">The session.</param> /// <param name="sessionFactory">The session factory.</param> internal static void CloseSessionOrRegisterDeferredClose(ISession session, ISessionFactory sessionFactory) { IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary; if (holderDictionary != null && sessionFactory != null && holderDictionary.Contains(sessionFactory)) { log.Debug("Registering Hibernate Session for deferred close"); // Switch Session to FlushMode.NEVER for remaining lifetime. session.FlushMode = FlushMode.Never; Set sessions = (Set)holderDictionary[sessionFactory]; sessions.Add(session); } else { CloseSession(session); } }
/// <summary> /// Creates the message queue given its name in the application context. /// </summary> /// <param name="messageQueueObjectName">Name of the message queue object.</param> /// <returns> /// A MessageQueue instance configured via the application context /// </returns> public MessageQueue CreateMessageQueue(string messageQueueObjectName) { AssertUtils.ArgumentHasText(messageQueueObjectName, "DefaultMessageQueueObjectName"); IDictionary queues = LogicalThreadContext.GetData(QUEUE_DICTIONARY_SLOTNAME) as IDictionary; if (queues == null) { queues = new Hashtable(); LogicalThreadContext.SetData(QUEUE_DICTIONARY_SLOTNAME, queues); } if (!queues.Contains(messageQueueObjectName)) { MessageQueue mq = applicationContext.GetObject(messageQueueObjectName) as MessageQueue; queues.Add(messageQueueObjectName, mq); } return(queues[messageQueueObjectName] as MessageQueue); }
/// <summary> /// Register a new transaction synchronization for the current thread. /// </summary> /// <remarks> /// Typically called by resource management code. /// </remarks> /// <exception cref="System.InvalidOperationException"> /// If synchronization is not active. /// </exception> public static void RegisterSynchronization(ITransactionSynchronization synchronization) { AssertUtils.ArgumentNotNull(synchronization, "TransactionSynchronization must not be null"); if (!SynchronizationActive) { throw new InvalidOperationException("Transaction synchronization is not active"); } ArrayList syncs = LogicalThreadContext.GetData(syncsDataSlotName) as ArrayList; if (syncs != null) { object root = syncs.SyncRoot; lock (root) { syncs.Add(synchronization); } } }
static void RunActionInBackground(object state) { WriteThreadInfo(); var action = state as Action<string>; var threadContext = new LogicalThreadContext(); var context = threadContext.Get<string>(ItemKey); action(context); }