- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
最近,当我尝试在 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 线程的线程中编写代码的规则。您必须做两件基本的事情:
您必须泵送消息循环。 Winforms 或 WPF 应用程序中的又名 Application.Run()。消息循环是一种基 native 制,通过它您可以让代码在特定线程上运行。它是 producer-consumer problem 的通用解决方案。这解决了线程安全问题,如果您始终从同一线程调用线程不安全代码,那么它就不再不安全了。
您绝不能阻塞您的线程。阻塞 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/
我正在编写一个 WPF 应用程序,该应用程序对具有简单要求的 API 具有可选依赖项;它必须在没有 STAThread 属性的线程上初始化/使用。当然,WPF 需要 STA,这样一切就变得简单了。 在
最近,当我尝试在 WinForm 中启动 OpenFileDialog 时,我的程序中遇到了与 STA 相关的错误。我已经阅读了一些内容,在将 [STAThread] 属性添加到主线程之前,我想知道它
我为 AutoCAD 编写了托管扩展。当 AutoCAD 加载扩展时,它会启动一些 IExtensionApplication.Initialize() 方法。我需要在应用程序的主 Thread 中启
摘自关于 STAThread 的 MSDN 文章: Indicates that the COM threading model for an application is single-thread
我正在学习 C# 3.5,我想知道 [STAThread] 在我们的程序中做了什么? 最佳答案 STAThreadAttribute 本质上是 Windows 消息泵与 COM 组件通信的要求。虽然核
我不完全理解 STATHREAD 属性的作用 http://msdn.microsoft.com/en-us/library/system.stathreadattribute.aspx .请看下面的
与奇怪的行为...... 大家好! 谁能解释一下,怎么会这样? 谢谢,亚历克斯。 最佳答案 我仍然觉得链接的答案有点难以接受,特别是因为 OP 承认他实际上没有有一个与 EXE 同名的 DLL。我也无
这是我尝试在我的程序中打开 OpenFileDialog 时收到的错误消息: "Current thread must be set to single thread apartment (STA)
我有一个外部组件 (C++),我想从我的 C# 代码中调用它。 代码是这样的: using System.Text; using System.Threading; using System.Thre
在 Watin 的 source code ,有这段代码: public void NavigateToNoWait(Uri url) { var thread = n
我想测试一个使用剪贴板 (WindowsForms) 的应用程序,我的单元测试中也需要剪贴板。为了使用它,它应该在 STA 模式下运行,但是由于 NUnit TestFixture 没有 main 方
基本上我已经为我的程序制作了一个登录系统,当用户登录时,它会打开 Form1。但我需要 Form1 成为 STA 线程。我在 Form1 中收到此错误: {"Current thread must b
我已经为 C# 控制台应用程序编写了代码。它将剪贴板中的值复制到文件中,并且运行时没有任何错误。 现在我想在另一个带有其他代码的 C# 项目中使用它。 我在 class{} 之后使用 [STAThre
当我们在 Main 中使用 STAThread 时,是否意味着我们不能从 Main 创建新线程? 最佳答案 不,它没有。大多数 UI 应用程序在 STA 线程中启动 - 它不会阻止它们启动新线程。 S
当您使用 Visual Studio 创建一个空的 WinForms 应用程序时,该模板在主应用程序类中具有 STAThread 属性。 我一直在阅读一些关于它的文档,但我不确定我是否完全理解它。 我
我对 C# 还是有点陌生,尤其是 C# 中的线程。我正在尝试启动一个需要单线程单元的函数 (STAThread) 但我无法编译以下代码: 该函数在名为 MyClass 的单独类中如下所示: int
当您使用 Visual Studio 创建一个空的 WinForms 应用程序时,该模板在主应用程序类中具有 STAThread 属性。 我一直在阅读一些关于它的文档,但我不确定我是否完全理解它。 我
我的代码有问题。我想这很简单,但我缺乏 OOP 和 C# 方面的经验,所以我不得不问你。 我的代码是这样的: namespace RR { static class Program {
我是 WPF 的新手,有几个关于 WPF 和 Windows 窗体集成的问题。 我有一个现有的 Visual C# Windows 窗体应用程序。我想将它与 WPF 窗口集成,单击按钮即可显示。这是不
我是 WPF 的新手,在我读过的每个教程中,他们都有一个 [System.STAThread]应用于其 Main 的属性方法,或者他们告诉读者这样做。 这个属性真的是“必需的”吗?如果是这样,为什么?
我是一名优秀的程序员,十分优秀!