为什么 WinForms 应用程序默认是 STAThread?

发布于 2024-07-05 11:39:22 字数 239 浏览 8 评论 0原文

当您使用 Visual Studio 创建空的 WinForms 应用程序时,模板在主应用程序类中具有 STAThread 属性。

我一直在阅读一些有关它的文档,但我不确定我是否完全理解它。

我确实有一些疑问:

  1. 为什么要添加这个属性?
  2. 这是什么意思?
  3. 如果删除此属性会发生什么?

When you create an empty WinForms application with Visual Studio, the template has the STAThread attribute in the main application class.

I have been reading some docs about it, but I'm not sure if I understood it at all.

Really I have some questions about it:

  1. Why is this attribute added?
  2. What does it mean?
  3. What happens if you remove this attribute?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

太阳公公是暖光 2024-07-12 11:39:22

引用MSDN 博客

当应用 STAThreadAttribute 时,它​​将当前线程的单元状态更改为单线程。 无需深入讨论 COM 和线程,此属性可确保当前线程与可能希望通过 COM 与其通信的其他线程之间的通信机制。 当您使用 Windows 窗体时,根据您使用的功能,它可能会使用 COM 互操作来与操作系统组件进行通信。 剪贴板和文件对话框就是很好的例子。

To quote from an MSDN blog,

When the STAThreadAttribute is applied, it changes the apartment state of the current thread to be single threaded. Without getting into a huge discussion about COM and threading, this attribute ensures the communication mechanism between the current thread and other threads that may want to talk to it via COM. When you're using Windows Forms, depending on the feature you're using, it may be using COM interop in order to communicate with operating system components. Good examples of this are the Clipboard and the File Dialogs.

山色无中 2024-07-12 11:39:22

这意味着 Windows 窗体程序使用单线程单元状态。 不支持 MTA 和自由线程单元状态。

It means that Windows Forms programs use a single-threaded apartment state. MTA and free threaded apartment states are not supported.

肥爪爪 2024-07-12 11:39:22

3.如果删除此属性会发生什么?

我只是添加一个简单的例子来说明问题。

我创建了带有按钮和 OpenFileDialog 的简单 WinForms 应用程序。 单击按钮时,我运行一个显示 openFileDialog 的线程。 我在使用和不使用 STAThread 的情况下启动应用程序,单击按钮的结果是相同的 - 它会抛出异常“跨线程操作无效:从创建它的线程以外的线程访问控制‘Form1’”。
看起来好像没有什么区别。 但不是。

然后我通过调用以下方法更改了 openFileDialog 的显示:

private void ShowOFD()
{
    if (InvokeRequired)
    {
        BeginInvoke(new Action(ShowOFD));
        return;
    }

    openFileDialog1.ShowDialog(this);
}

使用 STAThread,它按预期工作正常。 如果没有 STAThread,它会抛出异常:
“在进行 OLE 调用之前,当前线程必须设置为单线程单元 (STA) 模式。确保您的 Main 函数上标记有 STAThreadAttribute。仅当调试器附加到进程时才会引发此异常”。

然后我在没有调试器的情况下多次启动该应用程序(与 Visual Studio 分离)。 一次应用程序只是默默关闭,另一次应用程序关闭并显示消息“vshost 已停止工作”

3.What happens if you remove this attribute?

I just add a simple example which demonstrates the problem.

I created simple WinForms app with a button and an OpenFileDialog. On button click I run a thread which shows the openFileDialog. I launch the app with and without STAThread and results of clicking the button are the same - it throws the exception "Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on".
It looks as if there is no difference. But no.

Then I changed showing the openFileDialog by calling the method below:

private void ShowOFD()
{
    if (InvokeRequired)
    {
        BeginInvoke(new Action(ShowOFD));
        return;
    }

    openFileDialog1.ShowDialog(this);
}

With STAThread it works fine as expected. Without STAThread it throws the exception:
"Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it. This exception is only raised if a debugger is attached to the process".

Then I launch the app several times without debugger (detached from visual studio). One time the app just silently closed, another time the app closed with the message "vshost has stopped working"

情徒 2024-07-12 11:39:22

1. 为什么要添加这个属性?

因为它是 ActiveX 对象模型所需要的。 您可以将 ActiveX 控件放在 WinForm 上(因此它是为了兼容性)或某些 .NET 类使用需要该属性的本机控件。

2. 这是什么意思?

这意味着线程在单线程单元模型中运行。

3. 如果删除此属性会发生什么?

如果删除该属性,则行为未定义。 该程序可能会随机失败,有时会出现明显的错误消息。 例如,现在可能一切正常,然后由于服务包而中断。

1. Why is this attribute added?

Because it is required by the ActiveX object model. And you can drop ActiveX controls on a WinForm (so it is there for compatibility) OR some .NET classes use native controls which require that attribute.

2. What does it mean?

It means the thread runs in the single-threaded apartment model.

3. What happens if you remove this attribute?

If the attribute is removed, the behavior is undefined. The program may fail at random, with sometimes sensible error messages. For example, things may work now, then break with a service pack.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文