【问题标题】:Does the managed main UI thread stay on the same (unmanaged) Operation System thread?托管的主 UI 线程是否保留在同一(非托管)操作系统线程上?
【发布时间】:2010-05-07 07:46:27
【问题描述】:

我正在为旧版 Win32 应用程序创建托管 WPF UI 前端。 WPF 前端是可执行文件;作为其启动例程的一部分,我将旧版应用程序作为 DLL 在第二个线程中启动。旧版应用程序的任何 UI 操作(包括CreateWindowsEx 等)都会在主 UI 线程上调用。

作为应用程序关闭过程的一部分,我想正确清理。除其他外,我想在所有非托管窗口上调用DestroyWindow,以便它们可以正确清理自己。因此,在关机期间,我使用EnumWindows 来尝试查找我所有的非托管窗口。然后我将 DestroyWindow 称为我生成的列表之一。它们在主 UI 线程上运行。

在了解了这些背景知识之后,进入我的实际问题:
在 EnumWindows 的枚举过程中,我必须检查返回的顶级窗口之一是否是我的非托管窗口之一。我通过调用GetWindowThreadProcessId 来获取窗口创建者的进程ID 和线程ID 来做到这一点。我可以将进程 ID 与 Process.GetCurrentProcess().Id 进行比较,以检查我的应用是否创建了它。

为了提高安全性,我还想查看我的主 UI 线程是否创建了窗口。但是,返回的线程 id 是操作系统的 ThreadId(与托管线程 id 不同)。如this question 中所述,CLR 保留将托管线程重新调度到不同操作系统线程的权利。我是否可以依靠 CLR 来“足够聪明”以从不为主 UI 线程执行此操作(由于 UI 的线程相关性)?然后我可以调用GetCurrentThreadId 来获取主 UI 线程的非托管线程 id 进行比较。

【问题讨论】:

    标签: c# .net wpf multithreading pinvoke


    【解决方案1】:

    .NET 2.0 中为自定义 CLR 主机引入了将托管线程映射到自定义线程方案的功能。具体来说,SQL Server。他们想使用纤程,这是 SQL Server 的原生特性。他们做不下去了,项目被搁置了。据我所知,目前没有任何 CLR 主机真正利用了该功能。

    在默认 CLR 主机(即您在 WPF 应用程序中获得的主机)中永远不会出现问题。托管线程始终映射到一个操作系统线程,并且始终如此。您可以依赖 GetCurrentThreadId() 返回的值。我严重怀疑这会不会改变,这将是一个重大的突破性改变。对于类似于 Silverlight 的某种未来主机来说,这不太可能是真的,但您的代码永远不会接近这种情况。

    【讨论】:

    • 听起来如我所料。我想在任何地方都没有官方/半官方声明?
    猜你喜欢
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2015-09-03
    相关资源
    最近更新 更多