From 10633fdf9f876f49ff2428a9a1081ff03b7b912a Mon Sep 17 00:00:00 2001 From: Ami Bar Date: Fri, 6 Jul 2012 16:32:25 +0300 Subject: [PATCH] Added ApartmentState to threads + tests --- STPTests/STPTests.csproj | 1 + STPTests/TestThreadApartmentState.cs | 47 ++++++++++++++++++++++++++++ SmartThreadPool/STPStartInfo.cs | 24 ++++++++++++-- SmartThreadPool/SmartThreadPool.cs | 29 +++++++++++++---- 4 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 STPTests/TestThreadApartmentState.cs diff --git a/STPTests/STPTests.csproj b/STPTests/STPTests.csproj index 1ffdffc..877d1e6 100644 --- a/STPTests/STPTests.csproj +++ b/STPTests/STPTests.csproj @@ -109,6 +109,7 @@ Code + diff --git a/STPTests/TestThreadApartmentState.cs b/STPTests/TestThreadApartmentState.cs new file mode 100644 index 0000000..ea6d4f3 --- /dev/null +++ b/STPTests/TestThreadApartmentState.cs @@ -0,0 +1,47 @@ +using System.Threading; +using NUnit.Framework; +using Amib.Threading; + +namespace SmartThreadPoolTests +{ + /// + /// Summary description for TestThreadPriority. + /// + [TestFixture] + [Category("TestThreadApartment")] + public class TestThreadApartmentState + { + [Test] + public void TestSTA() + { + CheckApartmentState(ApartmentState.STA); + } + + [Test] + public void TestMTA() + { + CheckApartmentState(ApartmentState.MTA); + } + + private static void CheckApartmentState(ApartmentState requestApartmentState) + { + STPStartInfo stpStartInfo = new STPStartInfo(); + stpStartInfo.ApartmentState = requestApartmentState; + + SmartThreadPool stp = new SmartThreadPool(stpStartInfo); + + IWorkItemResult wir = stp.QueueWorkItem(() => GetCurrentThreadApartmentState()); + + ApartmentState resultApartmentState = wir.GetResult(); + + stp.WaitForIdle(); + + Assert.AreEqual(requestApartmentState, resultApartmentState); + } + + private static ApartmentState GetCurrentThreadApartmentState() + { + return Thread.CurrentThread.GetApartmentState(); + } + } +} \ No newline at end of file diff --git a/SmartThreadPool/STPStartInfo.cs b/SmartThreadPool/STPStartInfo.cs index d19a1d9..7454826 100644 --- a/SmartThreadPool/STPStartInfo.cs +++ b/SmartThreadPool/STPStartInfo.cs @@ -17,7 +17,7 @@ namespace Amib.Threading private bool _enableLocalPerformanceCounters; private string _threadPoolName = SmartThreadPool.DefaultThreadPoolName; - public STPStartInfo() + public STPStartInfo() { _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName; _threadPriority = SmartThreadPool.DefaultThreadPriority; @@ -37,8 +37,10 @@ namespace Amib.Threading _enableLocalPerformanceCounters = stpStartInfo._enableLocalPerformanceCounters; _threadPoolName = stpStartInfo._threadPoolName; _areThreadsBackground = stpStartInfo.AreThreadsBackground; +#if !(_SILVERLIGHT) + _apartmentState = stpStartInfo._apartmentState; +#endif } - /// /// Get/Set the idle timeout in milliseconds. @@ -160,5 +162,23 @@ namespace Amib.Threading { return new STPStartInfo(this) { _readOnly = true }; } + +#if !(_SILVERLIGHT) + + private ApartmentState _apartmentState = SmartThreadPool.DefaultApartmentState; + + /// + /// Get/Set the apartment state of threads in the thread pool + /// + public ApartmentState ApartmentState + { + get { return _apartmentState; } + set + { + ThrowIfReadOnly(); + _apartmentState = value; + } + } +#endif } } diff --git a/SmartThreadPool/SmartThreadPool.cs b/SmartThreadPool/SmartThreadPool.cs index 3865d00..af59014 100644 --- a/SmartThreadPool/SmartThreadPool.cs +++ b/SmartThreadPool/SmartThreadPool.cs @@ -7,7 +7,7 @@ // - Work items return result. // - Support waiting synchronization for multiple work items. // - Work items can be cancelled. -// - Passage of the caller thread’s context to the thread in the pool. +// - Passage of the caller thread’s context to the thread in the pool. // - Minimal usage of WIN32 handles. // - Minor bug fixes. // 26 Dec 2004 - Changes: @@ -159,13 +159,13 @@ namespace Amib.Threading /// public const ThreadPriority DefaultThreadPriority = ThreadPriority.Normal; - /// - /// The default fill state with params. (false) - /// /// The default thread pool name. (SmartThreadPool) /// public const string DefaultThreadPoolName = "SmartThreadPool"; + + /// + /// The default fill state with params. (false) /// It is relevant only to QueueWorkItem of Action<...>/Func<...> /// public const bool DefaultFillStateWithArgs = false; @@ -174,7 +174,16 @@ namespace Amib.Threading /// The default thread backgroundness. (true) /// public const bool DefaultAreThreadsBackground = true; - + +#if !(_SILVERLIGHT) + /// + /// The default apartment state of a thread in the thread pool. + /// The default is ApartmentState.Unknown which means the STP will not + /// set the apartment of the thread. It will use the .NET default. + /// + public const ApartmentState DefaultApartmentState = ApartmentState.Unknown; +#endif + #endregion #region Member Variables @@ -619,8 +628,16 @@ namespace Amib.Threading // Configure the new thread and start it workerThread.Name = "STP " + Name + " Thread #" + _threadCounter; workerThread.IsBackground = _stpStartInfo.AreThreadsBackground; + +#if !(_SILVERLIGHT) && !(_WINDOWS_CE) + if (_stpStartInfo.ApartmentState != ApartmentState.Unknown) + { + workerThread.SetApartmentState(_stpStartInfo.ApartmentState); + } +#endif + #if !(_SILVERLIGHT) - workerThread.Priority = _stpStartInfo.ThreadPriority; + workerThread.Priority = _stpStartInfo.ThreadPriority; #endif workerThread.Start(); ++_threadCounter;