.NET中STAThread的使用详解
Net 使用 详解
2023-06-13 09:14:52 时间
在WindowForm应用程序中主要的线程,是采用一种称为「Single-ThreadedApartment(STA)」的线程模型。这个STA线程模型,在线程内加入了讯息帮浦等等机制,减少开发人员撰写窗口程序的工作量。
而在开发类别库的时候,如果要使用类似的STA线程模型,可以使用下列的程序代码提供的类别来完成。
namespaceCLK.Threading
{
publicclassSTAThread
{
//Enum
privateenumThreadState
{
Started,
Stopping,
Stopped,
}
//Fields
privatereadonlyobject_syncRoot=newobject();
privatereadonlyBlockingQueue<Action>_actionQueue=null;
privateThread_thread=null;
privateManualResetEvent_threadEvent=null;
privateThreadState_threadState=ThreadState.Stopped;
//Constructor
publicSTAThread()
{
//ActionQueue
_actionQueue=newBlockingQueue<Action>();
//ThreadEvent
_threadEvent=newManualResetEvent(true);
//ThreadState
_threadState=ThreadState.Stopped;
}
//Methods
publicvoidStart()
{
//Sync
lock(_syncRoot)
{
//ThreadState
if(_threadState!=ThreadState.Stopped)thrownewInvalidOperationException();
_threadState=ThreadState.Started;
}
//Thread
_thread=newThread(this.Operate);
_thread.Name=string.Format("Class:{0},Id:{1}","STAThread",_thread.ManagedThreadId);
_thread.IsBackground=false;
_thread.Start();
}
publicvoidStop()
{
//Sync
lock(_syncRoot)
{
//ThreadState
if(_threadState!=ThreadState.Started)thrownewInvalidOperationException();
_threadState=ThreadState.Stopping;
//ActionQueue
_actionQueue.Release();
}
//Wait
_threadEvent.WaitOne();
}
publicvoidPost(SendOrPostCallbackcallback,objectstate)
{
#regionContracts
if(callback==null)thrownewArgumentNullException();
#endregion
//Action
Actionaction=delegate()
{
try
{
callback(state);
}
catch(Exceptionex)
{
Debug.Fail(string.Format("Delegate:{0},State:{1},Message:{2}",callback.GetType(),"Exception",ex.Message));
}
};
//Sync
lock(_syncRoot)
{
//ThreadState
if(_threadState!=ThreadState.Started)thrownewInvalidOperationException();
//ActionQueue
_actionQueue.Enqueue(action);
}
}
publicvoidSend(SendOrPostCallbackcallback,objectstate)
{
#regionContracts
if(callback==null)thrownewArgumentNullException();
#endregion
//Action
ManualResetEventactionEvent=newManualResetEvent(false);
Actionaction=delegate()
{
try
{
callback(state);
}
catch(Exceptionex)
{
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)thrownewInvalidOperationException();
//ActionQueue
if(Thread.CurrentThread!=_thread)
{
_actionQueue.Enqueue(action);
}
}
//Execute
if(Thread.CurrentThread==_thread)
{
action();
}
//Wait
actionEvent.WaitOne();
}
privatevoidOperate()
{
try
{
//Begin
_threadEvent.Reset();
//Operate
while(true)
{
//Action
Actionaction=_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();
}
}
}
}
namespaceCLK.Threading
{
publicclassBlockingQueue<T>
{
//Fields
privatereadonlyobject_syncRoot=newobject();
privatereadonlyWaitHandle[]_waitHandles=null;
privatereadonlyQueue<T>_itemQueue=null;
privatereadonlySemaphore_itemQueueSemaphore=null;
privatereadonlyManualResetEvent_itemQueueReleaseEvent=null;
//Constructors
publicBlockingQueue()
{
//Default
_itemQueue=newQueue<T>();
_itemQueueSemaphore=newSemaphore(0,int.MaxValue);
_itemQueueReleaseEvent=newManualResetEvent(false);
_waitHandles=newWaitHandle[]{_itemQueueSemaphore,_itemQueueReleaseEvent};
}
//Methods
publicvoidEnqueue(Titem)
{
lock(_syncRoot)
{
_itemQueue.Enqueue(item);
_itemQueueSemaphore.Release();
}
}
publicTDequeue()
{
WaitHandle.WaitAny(_waitHandles);
lock(_syncRoot)
{
if(_itemQueue.Count>0)
{
return_itemQueue.Dequeue();
}
}
returndefault(T);
}
publicvoidRelease()
{
lock(_syncRoot)
{
_itemQueueReleaseEvent.Set();
}
}
publicvoidReset()
{
lock(_syncRoot)
{
_itemQueue.Clear();
_itemQueueSemaphore.Close();
_itemQueueReleaseEvent.Reset();
}
}
}
}
相关文章
- 有点酷,使用 .NET MAUI 探索太空
- 使用.NET简单实现一个Redis的高性能克隆版
- 使用C#编写一个.NET分析器(一)
- 【愚公系列】2022年11月 .NET CORE工具案例-使用MailKit使用IMAP协议进行邮件读取
- SQL Server中调用C#类中的方法实例(使用.NET程序集)
- java.net.BindException: 地址已在使用 (Bind failed)详解程序员
- XX-Net使用:使用Chrome浏览器(二)详解程序员
- 使用XX-Net永久访问真正的互联网详解程序员
- Java使用commons-net实现FTP文件上传详解编程语言
- Oracle 等待事件 SQL*Net message to client 官方解释,作用,如何使用及优化方法
- .net让Oracle与ASP.NET实现无缝连接(oracleasp)
- 应用使用Linux环境部署.Net应用程序(linux部署.net)
- Net框架如何使用MySQL数据库(.net能用mysql吗)
- Net结合MySQL实现强劲的数据库运算(.net 用mysql)
- NET环境下MySQL数据库的使用实践(.net支持mysql吗)
- REDIS锁技术提升NET应用性能(redis 锁 .net)
- ASP.NET中JSON的序列化和反序列化使用说明
- ASP.NET中UpdatePanel与jQuery同时使用所遇问题解决
- ASP.NET笔记之Calender的使用说明
- 深入Lumisoft.NET组件POP3邮件接收与删除操作的使用详解
- 解析在.net中使用XSLT转换xml文档的示例详解
- Asp.net自带报表的使用详解
- 记录asp.net网站是什么原因导致停止运行的代码
- VB.NET中使用种子填充算法实现给图片着色的例子