[案例][STAThread]
[转发]
原文地址:http://blog.163.com/weizhiyong_111/blog/static/285970992009810517135
最近我遇到一个有趣的线程问题,想跟大家分享一下,以免大家也遇到这种容易混淆的问题。
打开一个其他人写的C#程序,为了下面的讲解,我把这个程序叫作”DeltaEngine”。DeltaEngine会调用一个本地的程序集,并处理其中某些事件。然后建一个工程,把DeltaEngine作为库项目引用,这个工程又被一个VB程序引用。我把这个VB程序叫做"VBApp"。所以,引用结构就像:
VBApp (VB) -> DeltaEngine (C#) -> NativeCode
当我把VBApp作为启动程序运行时,它会一直等待NativeCode里面的事件在DeltaEngine中被处理。我注意到,如果我把DeltaEngine作为启动程序来运行的话,事件就会像预期那样得到处理。我花了很多时间想解决这个问题,但还是很困惑。
最后有人指出,VB项目的默认线程模型是单线程套间(SingleThreaded Apartment),而C#项目的默认线程模型是多线程套间 (Multithreaded Apartment)。因为DeltaEngine最初是作为C#工程开发的,被默认为使用MTA。当使用VBApp作为启动程序调用DeltaEngine时,DeltaEngine就会使用STA。因为这样,DeltaEngine就会开始等待其实它已经唤起的事件,所以DeltaEngine会一直等待下去。如果我把DeltaEngine作为启动程序运行,它就会使用MTA并且会像预期那样工作。
解决的方法就是把MTAThreadAttribute加进VBApp的主函数里面。如下:
<MTAThread> Sub Main()
类似,如果你想把STAThread attribute加进C#的主方法里面,如下:
[STAThread]
static void Main()
WindowsForms程序要求使用STA,所以创建C# Winapp后,你可以在Program.cs看见像这样的代码。

浙公网安备 33010602011771号