关于[STAThread]

首先,我们了解一下[STAThread]语句的含义。

[STAThread]是指,single thread apartment thread - 单一套间线程

 

关于进程、线程、MTU、STU、COM之间的关系如下图所示:


网络上比较生动的解释是这样的:

进程相当于一个小城镇。

线程相当于这个城镇里的居民。

STA(单线程套间)相当于居民房,是私有的。

MTA(多线程套间)相当于旅馆,是公用的。

Com对象相当于居民房或旅馆里的物品。

 

接下去就好理解了,一个小城镇(进程)里可以有很多很多的(居民)线程,这个城镇(进程)只有一间旅馆(MTA),但可以有很多很多的居民房(STA)。

只有居民(线程)进入了房间(居民房或旅馆,STA或MTA)以后才能使用该房间里的物品(COM对象)。

居民房(STA)里的物品(COM对象)只能供这间房子的主人(创建该STA的线程)使用,其它居民(线程)不能访问。

同样,只有入住到旅馆(MTA)里的居民(线程,可以有多个)才可以访问到旅馆(MTA)里的物品(com对象),但因为是公用的,所以要合理的分配(同步)才能不会产生混乱。

 

线程是程序执行的最小单元。

STA (single threadapartment,单一线程套间),就是在COM库初始化的时候创建一个内存结构,然后让它和调用CoInitialize的线程相关联。这个内存结构针对每个线程都会有一个。支持STACOM对象只能在创建它的线程里被使用,其它线程如果再创建它就会失败。

 

MTA(multi threadapartment,多线程套间),COM库在进程中创建一个内存结构,这个内存结构在整个进程中只能有一个,然后让它和调用CoInitializeEx的线程相关联。支持MTACOM对象可以在任意线程里被使用。多有针对它的调用都会被封装成为消息。

其实STA和MTA是COM规定的一套线程模型,用于保障多线程情况下你的组件代码的同步。比如说有一个COM对象它内部有一个静态变量   gHello,那么这个对象无论生成多少实例对于gHello在内存中只能有一份,那么如果有两个不同的实例在两个线程里面同时去读写它,就有可能出错,所以就要就要有种机制进行同步保护,STA或者MTA就是这种机制。

 

他们是.NET支持的两种线程模式。

Apartment是逻辑上的概念,STA的apartment只包含一个线程(thread),相应的,MTA可以包含多个线程。从上面的描述可以看出:一个进程只有一个MTA,可以有多个STA;STA中的com只能由自身线程调用,MTA中的com可以由里面所有的线程调用。

STA 和MTA之间最大的区别是MTA可以在同一个apartment中使用所有的共享资源并发执行多个线程。而多个STA虽然可以共享数据,但是不能并发执行线程,存在性能问题。

好了,现在知道他们之间的关系,那么,程序是如何使用STA\MTA的呢?在何种情况下会使用呢?使用了对程序有什么影响呢?下面来一一解答。

 

STA用在程序的入口方法上,来指定当前线程的套间状态(apartmentState)是STA。

 

示例:

我现在想在一个windowsform的程序中实现从某个word文档复制图片并保存的方案。

具体是:打开word文档,将图片信息复制到粘贴板中,然后从粘贴板中取得图片信息,再保存到本地目录中。

说明:(本来是放在代码下面的,无奈POST之后就被代码挡住不显示了)

如果在某个按钮的事件中,直接调用该方法,那么界面将变得没有响应。所以我们需要考虑使用多线程来解决这个问题。Threadt = new Thread(new TheardStart(CopyImages); t.Start();

如果是这样,则程序会发生错误.。要么显示出现异常,要么没异常但是Clipboard为空,取不到任何数据!为什么呢?

因为Word.Application是Automation并且STA-Based,不能在没有指定ThreadApartment的线程中被调用。所以导致了各种错误,所以需要在t.Start();前面加上t.Apartment= ApartmentState.STA;这样就完全正常了。

对于MTA的多线程我们就见的比较多了,不再举例了。

另外一点不明白,我监视任务管理器发现,我在执行Threadt = new Thread(new TheardStart(CopyImages);t.Apartment = ApartmentState.STA;t.Start();之后该程序的进程中线程数从3个增加到6个,如果创建的是MTA的线程则只增加1。我的理解是STA线程为需要维护内部隐藏的窗口类和消息队列而增加的。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值