STA: Single-Thread Apartment,
中文叫单线程套间。就是在COM库初始化的时候创建一个内存结构,然后让它和调用CoInitialize的线程相关联。这个内存结构针对每个线程都会有
一个。支持STA的COM对象只能在创建它的线程里被使用,其它线程如果再创建它就会失败。
MTA:
Mutil-Thread
Apartment,中文叫多线程套间。COM库在进程中创建一个内存结构,这个内存结构在整个进程中只能有一个,然后让它和调用
CoInitializeEx的线程相关联。支持MTA的COM对象可以在任意线程里被使用。多有针对它的调用都会被封装成为消息。
其
实STA和MTA是COM规定的一套线程模型,用于保障多线程情况下你的组件代码的同步。比如说有一个COM对象它内部有一个静态变量
gHello,那么这个对象无论生成多少实例对于gHello在内存中只能有一份,那么如果有两个不同的实例在两个线程里面同时去读写它,就有可能出错,
所以就要就要有种机制进行同步保护,STA或者MTA就是这种机制。
.NET支持两种线程模型:STA和MTA。
STA(single threaded
apartments)。apartment只是一个逻辑上的概念,它可以包含一个或多个线程。一个AppDomain可以包括一个或多个
apartment。STA是指该apartment中只能包含一个thread。
MTA(multi threaded
apartments)。指该apartment中可以包含多个thread。
STA and
MTA之间最大的区别就是MTA可以在同一个apartment 中使用所有的共享资源并发执行多个线程。
而多个STA虽然可以共享数据,但是不能并发执行线程,存在性能问题。
线程的创建:
当创建一个新的STA线程时,CLR会在该
AppDomain中创建一个apartment和thread(从属于该apartment)。如果是创建MTA线程,则会CLR会检查该
AppDomain是否存在一个存放MTA的apartment,如果存在仅创建该线程到该MTA中,否则就创建一个MTA和thread(从属于该
apartment)。
我们可以设置线程的属性。例如 t.ApartmentState = ApartmentState.STA;
线
程的使用区别:
我们应该仅仅在访问STA-based 的COM组件时才使用STA线程模式。可以在注册表的HKEY_CLASSES_ROOT\CLSID\{Class ID of the COM component}
\InProcServer32
下查看到该COM的线程模式。如果该值是Apartment,则说明该COM只能以STA模式运行。其他的值有
Free(MTA),Both(STA+MTA),Single(只能在一个单一的线程中执行)。
其他情况下,我们应该使用MTA的线程,虽然需
要我们费心线程间资源的同步问题。
示例:
我现在想在一个windows
form的程序中实现从某个word文档复制图片并保存的方案。
具体是:打开word文档,将图片信息复制到粘贴板中,然后从粘贴板中取得图片信
息,再保存到本地目录中。
说明:(本来是放在代码下面的,无奈POST之后就被代码挡住不显示了
)
如果在某个按钮的事件中,直接调用该方法,那么界面将变得没有响应。所以我们需要考虑使用多线
程来解决这个问题。Thread t = new Thread(new TheardStart(CopyImages); t.Start();
如
果是这样,则程序会发生错误.。要么显示出现异常,要么没异常但是Clipboard为空,取不到任何数据!为什么呢?
因为
Word.Application
是Automation并且STA-Based,不能在没有指定ThreadApartment的线程中被调用。所以导致了各种错误,所以需要在
t.Start();前面加上t.Apartment = ApartmentState.STA;这样就完全正常了。
对于MTA的多线程我们就
见的比较多了,不再举例了。
另外一点不明白,我监视任务管理器发现,我在执行Thread t = new Thread(new
TheardStart(CopyImages);t.Apartment = ApartmentState.STA;
t.Start();之后该程序的进程中线程数从3个增加到6个,如果创建的是MTA的线程则只增加1。我的理解是STA线程为需要维护内部隐藏的窗口类
和消息队列而增加的。
下面是实现方法:
<!-- <br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->1
private
void
CopyImages()
2
{
3
Word.Applicationapp
=
null
;
4
Word.Documentdoc
=
null
;
5
6
app
=
new
ApplicationClass();
7
8
try
9
{
10
object
fileName
=
@"
E:\A.doc
"
;
11
doc
=
app.Documents.Open(
ref
fileName,
ref
missing,
ref
missing,
ref
missing,
ref
missing,
ref
missing,
ref
missing,
ref
missing,
ref
missing,
ref
missing,
12
ref
missing,
ref
missing,
ref
missing,
ref
missing,
ref
missing,
ref
missing);
13
14
int
count
=
doc.InlineShapes.Count;
15
for
(
int
i
=
1
;i
<=
count;i
++
)
16
{
17
doc.InlineShapes[i].Range.Copy();
18
19
if
(Clipboard.GetDataObject()
!=
null
)
20
{
21
IDataObjectdata
=
Clipboard.GetDataObject();
22
23
if
(data.GetDataPresent(DataFormats.Bitmap))
24
{
25
Imageimage
=
(Image)data.GetData(DataFormats.Bitmap,
true
);
26
image.Save(
"
E:\\
"
+
i.ToString()
+
"
.jpg
"
,System.Drawing.Imaging.ImageFormat.Jpeg);
27
}
28
else
29
{
30
lst_Items.Items.Add(doc.Name
+
"
;
无正确图片数据
"
);
31
}
32
}
33
else
34
{
35
lst_Items.Items.Add(doc.Name
+
"
;
粘贴板为空
"
);
36
}
37
}
38
39
}
40
catch
(Exceptionex)
41
{
42
lst_Items.Items.Add(doc.Name
+
"
发
生错误;
"
+
ex.Message);
43
}
44
finally
45
{
46
if
(doc
!=
null
)
47
doc.Close(
ref
missing,
ref
missing,
ref
missing);
48
if
(app
!=
null
)
49
app.Quit(
ref
missing,
ref
missing,
ref
missing);
50
}
分享到:
相关推荐
实现了一个STA组件, 然后里面有STA客户调用和MTA客户调用。
一个简单例子,MTA客户跨线程调用STA对象,直接传递COM对象。
无线通讯wifi模块AP和STA模式区别
STA1052 CD Servo Controller
openwrt总结(设置sta)
STA1052ROM3.1版本CD\MP3\WMA全功能
STA客户跨线程调用STA对象,使用了marshal,消息循环。
STA1050 CD Servo Controller
STA-LTA 算法和地震仪轨迹 3D 可视化 这是使用流行的 STA/LTA 算法检测地震 P 波的代码,具有 3D 地震仪轨迹的可视化和估计、S 波到达时间等等
Android8.0平台实现双wifi模块STA+AP模式
Step7语句表监控时RLO,STA,STANDARD的含义
STA508 is a monolithic quad half bridge stage in Multipower BCD technology. The device can be used as dual bridge or reconfigured, by connecting CONFIG pin to Vdd pin, as single bridge with double ...
sta-1040 sta sta
文档为oracle调优的STA无脑命令,直接安装命令贴到sqlplus里面就好,sql_id号从awr报告里面获得,想调优的语句找到sql_id,替换到文档里面的sql_id位置,最后无脑贴进去就可以使用STA调优助手了。
openwrt配置WiFi的AP+STA中继模式的关键步骤,内包含相关配置文件,以及uci2dat源码
很有用的音频放大集成块 STA328 很难找到的
RT3070 STA linux driver
RT2870STA.dat
51控制STA013实现MP3音频解码,实现了STA013的初始化、音量调节、静音、音质设置、声道控制。同时包含通过RS232串口控制LCD实现同步显示。代码经过调试,运行通过。
文件中包含 1、esp8266的sta模式模块 2、mp3模块