【发布时间】: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