c# - 为什么我们不能更改 ThreadPool 线程的单元状态,为什么我们在使用 ShowDialog 时不需要消息泵?

标签 c# winforms multithreading

最近遇到这种情况,我想在另一个线程(不是主/UI线程)上显示一个表单。我使用了线程池线程。该窗体托管了一个 RCW(用于 COM 组件)。实例化表单给了我一个线程必须是 STA 的异常。我试图将公寓状态设置为 STA。但是,那也没有用。我最终明确地创建了一个线程并且成功了(我使用了 ShowDialog 并且不需要创建一个 meesage 泵)。

编辑:

  • 我知道线程池线程是 MTA。但是,为什么不能设置成STA呢? 只是对此感到好奇。

  • 另一个突然出现在我脑海中的问题:为什么我们在使用 Showdialog()(显示表单)时不需要消息泵

最佳答案

通过调用 CoInitializeEx() 选择公寓。线程池中的线程已经进行了该调用,不可能在该调用之后更改单元。

线程池选择 MTA 是有道理的,毕竟它是作为工作线程使用的,不应被需要编码的方法调用阻塞。选择单线程单元还有一个额外的消息循环要求。一些您永远不会想到线程池线程会做的事情。

消息循环是必需的,因为它是 COM 用于编码在另一个线程上进行的调用的工具。该调用必须在 STA 线程中“注入(inject)”,只有当线程处于已知的静止状态时才有可能。如果不是,这样的调用会导致重大的重入问题。即使线程正在循环中,它有时也会这样做。

您不需要使用 Application.Run() 自己创建消息循环,因为 ShowDialog() 会启动它自己的消息循环。这就是它获得模态的方式。该嵌套循环在对话框关闭后立即退出。

关于c# - 为什么我们不能更改 ThreadPool 线程的单元状态,为什么我们在使用 ShowDialog 时不需要消息泵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1280867/

相关文章:

objective-c - 设置图像 : forState: lagging the UI

c# - Linq 按条件排序

c# - 更改 dataGridView CellFormatting 中单元格的文本

java - 如何在java中使用TCP/IP将相同的数据从服务器发送到所有客户端?

c# - 如何有效地从 TreeView 中删除选中的项目?

winforms - 在 WinForms MDI 中使用具有存储库模式的 Entity Framework

python - python运行多线程被挂起

c# - 如何简化那部分代码?

c# - EntityFramework 长时间运行任务的等待操作超时

c# - 使用给定的起点和终点从 html 中分离出一段数据