1

我刚刚从VS 2005升级到VS 2012。这是一个我不明白的新问题。我正在使用 VS 自动创建的默认“Form1”类。我添加了一个按钮来打开文件打开对话框,当我单击该按钮时出现此错误:

当前线程必须设置为单线程单元 (STA) 模式,然后才能进行 OLE 调用。确保您的 Main 函数上标记了 STAThreadAttribute。仅当调试器附加到进程时才会引发此异常。

我已将 " 添加到 Public Class Form1:

<STAThread()> Public Class Form1

但我明白这个...

属性“STAThreadAttribute”无法应用于“Form1”,因为该属性在此声明类型上无效。

我已经搜索过,但得到一些信息告诉我,我需要将入口点(我相信是 Form1)设置为单线程属性,但上面的代码不起作用。

如何?

4

1 回答 1

4

<STAThread()>属性不能添加到您的表单等类中。它在应用于Main函数时才有效,函数是应用程序的入口点。

但是 VB.NET 对你隐藏了这个功能,因为很少有人需要Main在 WinForms 应用程序中搞乱。只需要为您的应用程序设置管道,编译器可以为您管理。这由项目选项中的“应用程序框架”复选框控制。如果选中此项,编译器会自动生成Main函数和所需的管道。您可以禁用此选项,但对于普通的 WinForms 开发人员来说,这会使生活变得相当困难,因为您必须编写和维护自己的Main函数。

这里真正的问题是为什么这是一个问题。WinForms 应用程序的编译器生成的Main函数总是会应用STAThread属性。这就是 WinForms 框架的设计运行方式。如果这没有发生,那么您的项目就存在严重问题。我建议放弃它并重新开始让 Visual Studio 从内置模板之一创建一个新的 WinForms 项目。一切都应该只是工作™。

当然,另一种选择是您尝试OpenFileDialog在单独的线程(而不是您的主 UI 线程)上显示。但是根据您在问题中的描述(在表单中添加一个按钮以显示对话框),听起来情况并非如此。无论如何,解决方案不是那样做。例如,如果您使用 aBackgroundWorker在非 UI 线程上进行工作以保持 UI 响应,那很好,但您需要执行所有 UI 工作,例如之前OpenFileDialog在主 UI 线程上显示调用. 有一种方法可以使用该函数设置特定线程的单元状态,但我真的不建议在后台线程上显示。BackgroundWorkerSetApartmentStateOpenFileDialog

于 2013-08-28T22:20:04.533 回答