提问人:Dominique 提问时间:7/12/2023 最后编辑:Dominique 更新时间:7/13/2023 访问量:106
如何读取 C# 应用程序中的线程名称?
How can I read the name of a thread in a C# application?
问:
我正在开发一个用 C# 编写的多线程应用程序。 我想验证线程是否已经在运行。
你可能会想“这有多容易?”,但似乎有一个问题:
特此查看我的线程窗口的屏幕截图:
如您所见,有一个 ID 为 42940 的线程,其“Name”属性为“通知图标”。
现在,我正在调试以下源代码:
foreach (ProcessThread thread in currentThreads)
{
log.Debug($"Info about thread:Name=[], ID=[{thread.Id}], IsAlive=[]");
}
使用断点,我到达了 ID 为 42940 的线程。当我在监视窗口中显示此线程时,我看到的是:
如您所见,“thread”对象(ProcessThread 类的)似乎没有“Name”属性,尽管这在“Threads”窗口中非常明显。
我想访问源代码中的“Name”属性。
我该怎么做?
编辑:
显然,九年前有人问过同样的问题。看到我的问题是多么基本,我无法想象在九年的时间里,没有任何东西可以解决这个问题。有人有这方面的信息吗?如果还没有解决,有什么计划可以解决这个问题吗?
编辑(似乎根本不起作用):
我现在在我的项目中有以下代码:
foreach (ProcessThread thread in currentThreads)
{
var hThread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, false, thread.Id);
SetThreadDescription(hThread, "Naam van de thread");
var testdesc = GetThreadDescription(hThread, out string desc);
var testGetThreadId = GetThreadId(hThread);
log.Debug($"Info about thread:Name=[{desc}], ID=[{thread.Id}], description=[{testdesc}], testGetThreadId=[{testGetThreadId}]");
然而,变量的值始终是空字符串。desc
答:
也许您必须使用 Windows API:OpenThread
和 GetThreadDescription
。我尝试在 dotnet 源代码中搜索这些 API,但仅使用。SetThreadDescription
const int THREAD_QUERY_LIMITED_INFORMATION = 0x0800;
[LibraryImport("kernel32.dll", SetLastError = true)]
private static partial IntPtr OpenThread(int dwDesiredAccess,
[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwThreadId);
[LibraryImport("kernel32.dll", SetLastError = true)]
private static partial IntPtr GetThreadDescription(IntPtr hThread,
[MarshalAs(UnmanagedType.LPWStr)] out string ppszThreadDescription);
foreach (ProcessThread thread in currentThreads)
{
var hThread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, false, thread.Id);
GetThreadDescription(hThread, out string desc);
log.Debug($"Info about thread:Name=[{desc}], ID=[{thread.Id}], IsAlive=[]");
}
从Dominique编辑:由于前面的答案似乎不起作用,因此已添加以下源行并成功工作:
[DllImport("kernel32.dll", SetLastError = true)]
private static extern int GetThreadId(IntPtr hThread);
...
var testGetThreadId = GetThreadId(hThread);
log.Debug($"Info about thread:ID=[{thread.Id}], testGetThreadId=[{testGetThreadId}]");
=> 这证明使用 工作正常。现在我们需要确定为什么调用总是返回一个空字符串。DllImport
GetThreadDescription()
编辑2:
在“kernel32.dll”文件的“导出”列表中有一件奇怪的事情:
C:\"Program Files"\"Microsoft Visual Studio"\2022\Enterprise\SDK\ScopeCppSDK\vc15\VC\bin\dumpbin.exe /EXPORTS C:\Windows\System32\kernel32.dll
...
769 300 000255C0 GetTempPathW
770 301 00020CF0 GetThreadContext
771 302 GetThreadDescription (forwarded to api-ms-win-core-processthreads-l1-1-3.GetThreadDescription)
772 303 0003BA40 GetThreadErrorMode
773 304 0003BA60 GetThreadGroupAffinity
...
也许这些东西导致该功能不起作用?forwarded
评论
LibraryImport
SetLastError
MarshalAs
UnManagedType
.NET Framework 4.6.1
4.8
LibraryImport
[DllImport("kernel32.dll", SetLastError = true)]
[DllImport("C:\\Windows\\SysWOW64\\kernel32.dll", SetLastError = true)]
var test = GetThreadDescription(...)
评论
Microsoft.Diagnostics.Runtime
*unsafe*.dll