.NET中STAThread的使用详解

所属分类: 网络编程 / ASP.NET 阅读数: 1807
收藏 0 赞 0 分享

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

而在开发类别库的时候,如果要使用类似的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();
            }
        }
    }
}

更多精彩内容其他人还在看

运行page页面时的事件执行顺序及页面的回发与否深度了解

page页面时的事件执行顺序的了解对于一些.net开发者起到者尤关重要的作用;页面的回发与否会涉及到某些事件执行与不执行,在本文中会详细介绍,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

Web.config(应用程序的配置信息)总结

Web.config文件是一个XML文本文件,它用来储存 ASP.NET Web 应用程序的配置信息(如最常用的设置ASP.NET Web 应用程序的身份验证方式),它可以出现在应用程序的每一个目录中,接下来详细介绍一下配置情况,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

C#时间格式化(Datetime)用法详解

C#时间格式化Datetime.ToString参数format格式详细用法,本文将进行介绍,感兴趣的朋友可以了解下啊
收藏 0 赞 0 分享

实现onmouseover和onmouseout应用于RadioButtonList或CheckBoxList控件上

一直想实现onmouseover和onmouseout应用于RadioButtonList或CheckBoxList控件上。此功能就是当鼠标经过时RadioButtonList或CheckBoxList每一个Item时,让Item有特效显示,离开时,恢复原样有演示动画,感兴趣的朋
收藏 0 赞 0 分享

Asp.net 图片文件防盗链(尊重劳动成果)及BeginRequest事件学习

关于图片盗链这个问题,毕竟是自己的劳动成功,很多人不希望别人就那么轻易地偷走了;反盗链的程序其实很简单,熟悉ASP.NET 应用程序生命周期的话很容易就可以写一个,运用HttpModule在BeginRequest事件中拦截请求就ok了
收藏 0 赞 0 分享

asp.net Grid 导出Excel实现程序代码

看了FineUI中的将Grid导出为Excel的实现方法,实际上是可以非常简单。看来很难的问题,变换一种思路就可以非常简单
收藏 0 赞 0 分享

使用C#处理WebBrowser控件在不同域名中的跨域问题

我们在做web测试时,经常会使用WebBrowser来进行一些自动化的任务而有些网页上面会用IFrame去嵌套别的页面,这些页面可能不是在相同域名下的,这时就会出现跨域问题,无法直接在WebBrowser中获取到IFrame中的元素,接下来介绍如何解决此问题,需要了解的朋友可以参
收藏 0 赞 0 分享

.NET 下运用策略模式(组合行为和实体的一种模式)

我简单的理解策略模式就是把行为(方法)单独的抽象出来,并采用组合(Has-a)的方式,来组合行为和实体的一种模式比如,.NET中对数组排序的Sort的方法就是一个策略模式的实现模板
收藏 0 赞 0 分享

使用Entity Framework(4.3.1版本)遇到的问题整理

在这里记录一下之前使用Entity Framework(4.3.1版本)遇到的问题:更新没有设置主键的表、更改Code-First的默认连接、检测字符串截断错误,需要的朋友可以参考下
收藏 0 赞 0 分享

Asp.net利用JQuery AJAX实现无刷新评论思路与代码

Asp.net利用JQuery AJAX实现无刷新评论,此功能是每一个从事asp.net开发者的朋友都希望实现的,本文利用闲暇时间整理了一些,有需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多