代码之家  ›  专栏  ›  技术社区  ›  Daniel Rose

托管主ui线程是否保持在同一个(非托管)操作系统线程上?

  •  0
  • Daniel Rose  · 技术社区  · 14 年前

    我正在为遗留的win32应用程序创建一个受管理的wpf ui前端。wpf前端是可执行文件;作为其启动例程的一部分,我在第二个线程中将旧版应用程序作为dll启动。任何用户界面操作(包括 CreateWindowsEx ,等等)由遗留应用程序在主ui线程上调用。

    作为应用程序关闭过程的一部分,我要正确清理。除此之外,我想打电话给 DestroyWindow 在所有未被管理的窗口上,这样他们可以正确地清理自己。因此,在关机期间,我使用 EnumWindows 试图找到我所有的非托管窗口。然后我把destroywindow one称为我生成的列表。它们在主ui线程上运行。

    在了解了这些背景知识之后,请回答我的实际问题:
    在EnumWindows的枚举过程中,我必须检查返回的顶级窗口中是否有一个是我的非托管窗口。我是打电话来的 GetWindowThreadProcessId 获取窗口创建者的进程ID和线程ID。我可以将进程id与 Process.GetCurrentProcess().Id 检查我的应用是否创建了它。

    为了增加安全性,我还想看看我的主ui线程是否创建了窗口。但是,返回的线程id是操作系统的线程id(与托管线程id不同)。如中所述 this question ,CLR保留将托管线程重新调度到不同OS线程的权利。我是否可以依赖clr“足够聪明”而不为主ui线程执行此操作(由于ui的线程关联性)?然后我可以打电话 GetCurrentThreadId 获取主ui线程的非托管线程id以进行比较。

    1 回复  |  直到 14 年前
        1
  •  2
  •   Hans Passant    14 年前

    在.NET2.0中为自定义CLR主机引入了将托管线程映射到自定义线程方案的功能。特别是SQL Server。他们想使用fibers,这是sql server的本机特性。他们做不到,这个项目被搁置了。目前还没有一个clr主机真正利用了这个特性。

    在默认的clr主机(wpf应用程序中的主机)中,这永远不会成为问题。托管线程始终映射到一个OS线程,并且始终如此。您可以依赖getcurrentThreadID()返回的值。我严重怀疑这种情况是否会改变,这将是一个重大的突破性改变。类似于silverlight的未来主机不太可能是这样,但是您的代码永远不会接近它。