zoukankan      html  css  js  c++  java
  • [.NET] STAThread

    在WindowForm应用程序中主要的线程,是采用一种称为「Single-Threaded Apartment(STA)」的线程模型。这个STA线程模型,在线程内加入了讯息帮浦等等机制,减少开发人员撰写窗口程序的工作量。相关的信息可以参考:[Object-oriented] 线程

    而在开发类别库的时候,如果要使用类似的STA线程模型,可以使用下列的程序代码提供的类别来完成。

    namespace CLK.Threading
    {
        public class STAThread
        {
            // Enum
            private enum ThreadState
            {
                Started,
                Stopping,
                Stopped,
            }
    
    
            // Fields
            private readonly object _syncRoot = new object();
    
            private readonly BlockingQueue<Action> _actionQueue = null;
    
            private Thread _thread = null;
    
            private ManualResetEvent _threadEvent = null;
    
            private ThreadState _threadState = ThreadState.Stopped;       
    
    
            // Constructor
            public STAThread()
            {
                // ActionQueue
                _actionQueue = new BlockingQueue<Action>();
                            
                // ThreadEvent
                _threadEvent = new ManualResetEvent(true);
    
                // ThreadState
                _threadState = ThreadState.Stopped;       
            }
    
    
            // Methods
            public void Start()
            {            
                // Sync
                lock (_syncRoot)
                {
                    // ThreadState
                    if (_threadState != ThreadState.Stopped) throw new InvalidOperationException();
                    _threadState = ThreadState.Started;
                }
    
                // Thread
                _thread = new Thread(this.Operate);
                _thread.Name = string.Format("Class:{0}, Id:{1}", "STAThread", _thread.ManagedThreadId);
                _thread.IsBackground = false;
                _thread.Start();
            }
    
            public void Stop()
            {
                // Sync
                lock (_syncRoot)
                {
                    // ThreadState
                    if (_threadState != ThreadState.Started) throw new InvalidOperationException();
                    _threadState = ThreadState.Stopping;
    
                    // ActionQueue
                    _actionQueue.Release();
                }
    
                // Wait
                _threadEvent.WaitOne();
            }
    
    
            public void Post(SendOrPostCallback callback, object state)
            {
                #region Contracts
    
                if (callback == null) throw new ArgumentNullException();
    
                #endregion
                
                // Action
                Action action = delegate()
                {
                    try
                    {
                        callback(state);
                    }
                    catch (Exception ex)
                    {
                        Debug.Fail(string.Format("Delegate:{0}, State:{1}, Message:{2}", callback.GetType(), "Exception", ex.Message));
                    }
                };
    
                // Sync
                lock (_syncRoot)
                {
                    // ThreadState
                    if (_threadState != ThreadState.Started) throw new InvalidOperationException();
    
                    // ActionQueue
                    _actionQueue.Enqueue(action);
                }                       
            }
    
            public void Send(SendOrPostCallback callback, object state)
            {
                #region Contracts
    
                if (callback == null) throw new ArgumentNullException();
    
                #endregion
    
                // Action 
                ManualResetEvent actionEvent = new ManualResetEvent(false);
                Action action = delegate()
                {
                    try
                    {
                        callback(state);
                    }
                    catch (Exception ex)
                    {
                        Debug.Fail(string.Format("Delegate:{0}, State:{1}, Message:{2}", callback.GetType(), "Exception", ex.Message));
                    }
                    finally
                    {
                        actionEvent.Set();
                    }
                };
    
                // Sync
                lock (_syncRoot)
                {
                    // ThreadState
                    if (_threadState != ThreadState.Started) throw new InvalidOperationException();
    
                    // ActionQueue
                    if (Thread.CurrentThread != _thread)
                    {
                        _actionQueue.Enqueue(action);
                    }
                }
    
                // Execute
                if (Thread.CurrentThread == _thread)
                {
                    action();
                }
    
                // Wait
                actionEvent.WaitOne();
            }
    
    
            private void Operate()
            {
                try
                {
                    // Begin
                    _threadEvent.Reset();
    
                    // Operate
                    while (true)
                    {
                        // Action
                        Action action = _actionQueue.Dequeue();
    
                        // Execute
                        if (action != null)
                        {
                            action();
                        }
                                            
                        // ThreadState
                        if (action == null)
                        {
                            lock (_syncRoot)
                            {
                                if (_threadState == ThreadState.Stopping)
                                {
                                    return;
                                }
                            }
                        }
                    }
                }
                finally
                {
                    // End
                    lock (_syncRoot)
                    {
                        _threadState = ThreadState.Stopped;
                    }
                    _threadEvent.Set();
                }
            }
        }
    }
    
    namespace CLK.Threading
    {
        public class BlockingQueue<T>
        {
            // Fields        
            private readonly object _syncRoot = new object();
    
            private readonly WaitHandle[] _waitHandles = null;
    
            private readonly Queue<T> _itemQueue = null;
    
            private readonly Semaphore _itemQueueSemaphore = null;
    
            private readonly ManualResetEvent _itemQueueReleaseEvent = null;
    
    
            // Constructors
            public BlockingQueue()
            {
                // Default 
                _itemQueue = new Queue<T>();
                _itemQueueSemaphore = new Semaphore(0, int.MaxValue);
                _itemQueueReleaseEvent = new ManualResetEvent(false);
                _waitHandles = new WaitHandle[] { _itemQueueSemaphore, _itemQueueReleaseEvent };
            }
    
    
            // Methods
            public void Enqueue(T item)
            {
                lock (_syncRoot)
                {
                    _itemQueue.Enqueue(item);
                    _itemQueueSemaphore.Release();
                }
            }
    
            public T Dequeue()
            {
                WaitHandle.WaitAny(_waitHandles);
                lock (_syncRoot)
                {
                    if (_itemQueue.Count > 0)
                    {
                        return _itemQueue.Dequeue();
                    }
                }
                return default(T);
            }
    
            public void Release()
            {
                lock (_syncRoot)
                {
                    _itemQueueReleaseEvent.Set();
                }
            }
    
            public void Reset()
            {
                lock (_syncRoot)
                {
                    _itemQueue.Clear();
                    _itemQueueSemaphore.Close();
                    _itemQueueReleaseEvent.Reset();
                }
            }
        }
    }
    


  • 相关阅读:
    fedora 20 install skype
    WebsitePanel(wsp)配置详解(安装指南)
    【转】SQL Server 2008下载 (附注册码)
    SQL SERVER树型数据处理时,函数递归调用问题,查询根节点,子节点函数
    150 Opening ASCII mode data connection. FTP连接的PASV和PORT方式
    如何在IIS7上配置 FTP7并使用IIS管理凭据方式进行验证?
    DZ!NT论坛 3.6.711删除用户各种错解决方案
    在虚拟机上安装红帽Linux.5.5.for.x86.服务器版系统(按针对安装oracle 10g作的配置)
    OpenStack Nova 制作 Windows 镜像
    HttpWebRequest访问时,错误:(401)未经授权。
  • 原文地址:https://www.cnblogs.com/clark159/p/2658982.html
Copyright © 2011-2022 走看看