gpt4 book ai didi

c# - STAThread 将如何影响我的多线程程序

转载 作者:行者123 更新时间:2023-12-02 17:40:12 24 4
gpt4 key购买 nike

最近,当我尝试在 WinForm 中启动 OpenFileDialog 时,我的程序中遇到了与 STA 相关的错误。我已经阅读了一些内容,在将 [STAThread] 属性添加到主线程之前,我想知道它将如何影响我的程序的执行。
我对 COM 是个外国人,所以并不是我读到的所有内容都对我有意义。令我印象深刻的一些要点是:

The [STAThread] attribute defines the application as using a single-threaded apartment model. More specifically, it changes the state of the application thread to be single-threaded. http://www.a2zdotnet.com/View.aspx?Id=93

The STA architecture can impose significant performance penalties when an object is accessed by many threads. Each thread's access to the object is serialized and so each thread must wait in line for its turn to have a go with the object.
http://www.codeproject.com/Articles/9190/Understanding-The-COM-Single-Threaded-Apartment-Pa

我了解线程安全的必要性,但我仍然不明白 STAThread 的作用。在我的程序(我从另一位开发人员那里继承的)中,主线程启动了几个其他线程,其中一个线程初始化了 UI 表单 - 我认为这就是问题出现的地方。添加了 [STAThread] 后,新线程会发生什么?这会影响非 Windows 对象的多线程通信吗?

当我尝试在其中一个表单中打开 OpenFileDialog 时,会发生错误。我使用 VS 设计器将对话框添加到表单中:它不起作用。然后,我尝试在由主线程运行的全局文件中创建一个对话框,并从我的表单中调用该实例。没有效果。

最佳答案

[STAThread] 或 Thread.SetApartmentState() 确实非常非常重要。您向操作系统 promise 您编写的代码表现良好。它对于 Windows 内的大量代码以及您使用的非线程安全组件很重要。此类代码的标准示例包括剪贴板、拖放、外壳对话框(如 OpenFileDialog)、WebBrowser 等组件以及由 .NET 类包装的许多 Windows 子组件。

线程安全始终是一件大事,编写真正的线程安全代码非常非常困难。 .NET Framework 本身很少能实现这一点。非常基本的类列表 List<> 不是线程安全的。

为了使 promise 表现良好,您必须遵守在报告自身是 STA 线程的线程中编写代码的规则。您必须做两件基本的事情:

  1. 您必须泵送消息循环。 Winforms 或 WPF 应用程序中的又名 Application.Run()。消息循环是一种基 native 制,通过它您可以让代码在特定线程上运行。它是 producer-consumer problem 的通用解决方案。这解决了线程安全问题,如果您始终从同一线程调用线程不安全代码,那么它就不再不安全了。

  2. 您绝不能阻塞您的线程。阻塞 STA 线程非常很可能导致死锁。因为它会阻止那些非线程安全的代码块被调用。 CLR 对此有核心支持,使用 WaitOne() 阻塞 STA 线程会导致它本身泵送消息循环。

这些要求可以在 Winforms 或 WPF 应用程序中轻松满足。它们是完全旨在帮助您实现它们的类库。他们行为方式的几乎每一个方面都受到了它的影响。

必须将 GUI 应用程序中的 Main() 方法标记为 [STAThread]。创建窗口时的严格要求。

支持并且可以创建另一个显示窗口的线程。这次你必须调用SetApartmentState()来切换到STA,它不能是线程池线程。做到这一点非常困难,在 Winforms 中,如果您使用某种类型的控件,您将被 SystemEvents 类严重困扰。它有一个技巧,就是在错误的线程上开始引发事件。调试此类问题需要黑带技能,look like this 。这应该会吓到你。

关于c# - STAThread 将如何影响我的多线程程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24335850/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com