【发布时间】:2018-03-14 13:07:31
【问题描述】:
我设法用 C# 编写了一个相对较大的 WinForms 应用程序,它可以在没有 Main() 方法上的 [STAThread] 属性的情况下正常运行。
为此,我必须重写许多 WinForms 功能(例如使用自定义 BeginInvoke 和 Invoke 函数),使用自定义消息循环而不是 Application.Run,使用自定义文件对话框而不是 @ 987654330@ 和 SaveFileDialog,并使用 WM_DROPFILES 进行拖放,而不是 WinForms 开箱即用的 OLE 方法。这都是“为了科学”。
现在我想测试在所有 GUI 线程中省略 STAThreadAttribute 可能对性能造成的影响。我对Control 类内部使用的COM 配置的了解不够深入,无法预测这种影响。执行速度可能取决于哪个线程正在调用Control 的内部 COM 对象。
诚然,我无法提出一个测试与[STAThread] 相关的性能影响的基准,因为我不确定哪些功能/操作会受到这种更改的影响(特别是与Control类)。
我究竟应该寻找什么?通过省略[STAThread](如果有),我应该期望Control 类中的哪些操作/方法运行得更快/更慢?
附录:理由是我正在慢慢迁移我的应用程序以使用自定义窗口系统(出于便携性原因,主要是在 Linux 上使用 Mono,其 WinForms 实现不完整),所以我无论如何,我不得不自己重写很多功能。只是一个巧合,我注意到我已经覆盖了很多功能,以至于我可以省略 [STAThread] 并且一切仍将按预期工作。
由于来自ThreadPool(配置为 MTA)和 GUI 线程(默认情况下应配置为 STA)的 COM 编组调用,我预计性能会发生变化。从 ThreadPool 到 GUI 线程的调用需要编组,因为它们被配置在不同的线程单元中,这会引入同步开销。通过将 GUI 线程保留为 MTA,应该减少编组,因此可能更快地执行函数调用。我想实际地测试一下这个说法。
【问题讨论】:
-
基于此; stackoverflow.com/questions/1361033/what-does-stathread-do,不建议删除此属性,因为 WinForms 不保证正确执行。删除属性的原因是什么?
-
您为什么预计性能会发生(可衡量的)变化?
-
我更新了问题以回答两个 cmets。
-
STA/MTA 仅适用于 COM(此处必须是 UI 控件)。我相信任何 UI 控件都只能在 STA(通常是主 STA)中运行。如果您以某种方式设法让您的主 UI 线程进入 MTA,则必须编组从 MTA 到控件 STA 的所有调用。我什至不确定这将如何工作。您必须通过代理调用的 COM 指针进行调用。直接通过普通指针调用似乎可以工作,因为一切都在进行中。但是,您不再遵守规则,并且有一天您的代码很可能会因为竞态条件而失败。
标签: c# .net winforms performance com