.NET中STAThread的使用详解

你静候着秋天的温柔,留我在风景之外。把眼睛留给风光,把体重留给美食。我坐在椅子上,看日出复活;我坐在夕阳里,看城市的衰落。

在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();
}
}
}
}

到此这篇关于.NET中STAThread的使用详解就介绍到这了。关于过去,关于你,告一段落;关于未来,关于我,敬请期待。更多相关.NET中STAThread的使用详解内容请查看相关栏目,小编编辑不易,再次感谢大家的支持!

您可能有感兴趣的文章
ASP.NET中Response.BufferOutput属性的使用技巧

ASP.NET轻量级MVC框架Nancy的基本用法

ASP.NET Core中的对象池介绍

.NET集成ORM框架HiSql

asp.net中MVC的处理流程详解