2010-05-07 43 views
0

我正在为传统Win32应用程序创建托管WPF UI前端。 WPF前端是可执行文件;作为其启动例程的一部分,我在第二个线程中将遗留应用程序作为DLL启动。在主UI线程上调用传统应用程序的任何UI操作(包括CreateWindowsEx等)。托管的主UI线程是否停留在同一个(非托管的)操作系统线程上?

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

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

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

回答

2

在.NET 2.0中为自定义CLR主机引入了将托管线程映射到自定义线程方案的功能。特别是,SQL Server。他们想使用光纤,这是SQL Server的本地特性。他们无法摆脱它,项目被搁置。我现在没有注意到CLR主机实际上利用了该功能。

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

+0

这听起来像我的预期。我认为在这个地方没有官方/半官方声明? – 2010-05-07 14:20:53

相关问题