我正在开发基于.NET 2.0插件的应用程序。我的应用程序通过System.Reflection检查指定目录中的其他.NET程序集,在运行时检测/加载插件。这非常有效。我的应用程序包含一个PropertyGrid控件,该控件是从加载的插件中存在的[Browsable(true)]属性填充的。在此PropertyGrid中,browsable-true-properties表现出以下行为:
使用Visual Studio .NET 2005和Red Gate的Reflector,我能够将挂起与Microsoft.Win32.SystemEvents.WindowThreadProc中的以下代码段隔离开来(我正在使用原始程序集,但我99%肯定这是正确的地方):
while (flag)
{
if (UnsafeNativeMethods.MsgWaitForMultipleObjectsEx(0, IntPtr.Zero, 100, 0xff, 4) != 0x102)
{
goto Label_0072;
}
Thread.Sleep(1);
continue;
Label_0053:
if (msg.message == 0x12)
{
flag = false;
continue;
}
UnsafeNativeMethods.TranslateMessage(ref msg);
UnsafeNativeMethods.DispatchMessage(ref msg);
Label_0072:
if (UnsafeNativeMethods.PeekMessage(ref msg, NativeMethods.NullHandleRef, 0, 0, 1))
{
goto Label_0053;
}
}
似乎'flag'未设置为true,因此我的程序永远位于此循环中。我找到了a similar problem at .NET 247的人,但他推荐的解决方法是:
System.Threading.Thread.CurrentThread.SetApartmentState(Threading.ApartmentState.STA)
似乎无法解决问题。
有什么想法吗?
提前致谢。
答案 0 :(得分:3)
确保您的应用程序的入口点被标记[STAThread]
- STAThreadAttribute是.NET 2+中将UI线程标记为STA的唯一方法。在线程启动后设置ApartmentState(在1.1中工作)不再是有效的指导。
这应该是:
public class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MyMainForm());
}
}
答案 1 :(得分:0)
看起来你已经错误地隔离了这个问题。您发布的代码是针对WinForms用于捕获系统窗口消息(如WM_SETTINGCHANGE)的不可见窗口的窗口过程。它运行在与主线程不同的线程上,因此它不应以任何方式影响它。如果您刚刚将调试器附加到您的进程,很可能您的错误线程。
这里的标志实际上是在窗口获得WM_QUIT时设置的。但是,这应该没关系,因为线程也是作为后台线程创建的,这意味着当你的主线程终止时它会被杀死 - 所以即使没有设置标志并且它保持循环,它仍然会赢得'暂停应用程序退出。
(如果您查看使用VS2008 SP1的MS调试源服务器提供的.NET源代码,上述所有内容都很容易找到。)
答案 2 :(得分:0)
供将来偶然发现的人参考:
Friend Class Starter
<STAThread()> _
Shared Sub Main()
Application.EnableVisualStyles()
Dim client As ClientGUI
client = New ClientGUI()
Application.Run(client)
My.Settings.Save()
End Sub
End Class