- Thread. Current Thread Свойство
- Определение
- Значение свойства
- Примеры
- GetCurrentThread function (processthreadsapi.h)
- Syntax
- Parameters
- Return value
- Remarks
- How to get the main thread ID of a process (known by its ID)?
- 6 Answers 6
- Getting the thread ID from a thread
- 11 Answers 11
- View threads in the Visual Studio debugger by using the Threads window (C#, Visual Basic, C++)
- Use the Threads window
- To display the Threads window in break mode or run mode
- To display or hide a column
- Display flagged threads
- To display only flagged threads
- Freeze and thaw threads
- To freeze or thaw execution of a thread
- Switch to another thread
- To switch to another thread
- Group and sort threads
- To sort threads
- To group threads
- To sort threads within groups
- To expand or collapse all groups
- Search for specific threads
- To search for specific threads
- Display thread call stacks and switch between frames
- To view the call stack of a thread
Thread. Current Thread Свойство
Определение
Возвращает выполняющийся в данный момент поток. Gets the currently running thread.
Значение свойства
Объект Thread, представляющий собой выполняющийся в данный момент поток. A Thread that is the representation of the currently running thread.
Примеры
В следующем примере создается задача, которая, в свою очередь, создает 20 дочерних задач. The following example creates a task that in turn creates 20 child tasks. Само приложение, а также каждая задача вызывает ShowThreadInformation метод, который использует CurrentThread свойство для вывода сведений о потоке, в котором он выполняется. The application itself, as well as each task, calls the ShowThreadInformation method, which uses the CurrentThread property to display information about the thread on which it is running.
Каждая дочерняя задача создает 1 000 000 случайных чисел от 1 до 1 000 000 и возвращает их среднее значение. Each child task generates 1 million random numbers between 1 and 1 million and returns their mean. Родительская задача вызывает Task.WaitAll метод, чтобы убедиться, что дочерние задачи завершены до отображения среднего значения, возвращаемого каждой задачей, и вычисления средних значений. The parent task calls the Task.WaitAll method to ensure that the child tasks have completed before displaying the mean returned by each task and calculating the mean of means.
Обратите внимание, что хотя приложение выполняется в потоке переднего плана, каждая задача выполняется в потоке пула потоков. Note that while the application runs on a foreground thread, each task runs on a thread pool thread.
GetCurrentThread function (processthreadsapi.h)
Retrieves a pseudo handle for the calling thread.
Syntax
Parameters
This function has no parameters.
Return value
The return value is a pseudo handle for the current thread.
Remarks
A pseudo handle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required. Pseudo handles are not inherited by child processes.
This handle has the THREAD_ALL_ACCESS access right to the thread object. For more information, see Thread Security and Access Rights.
Windows ServerВ 2003 and WindowsВ XP:В В This handle has the maximum access allowed by the security descriptor of the thread to the primary token of the process.
The function cannot be used by one thread to create a handle that can be used by other threads to refer to the first thread. The handle is always interpreted as referring to the thread that is using it. A thread can create a «real» handle to itself that can be used by other threads, or inherited by other processes, by specifying the pseudo handle as the source handle in a call to the DuplicateHandle function.
The pseudo handle need not be closed when it is no longer needed. Calling the CloseHandle function with this handle has no effect. If the pseudo handle is duplicated by DuplicateHandle, the duplicate handle must be closed.
Do not create a thread while impersonating a security context. The call will succeed, however the newly created thread will have reduced access rights to itself when calling GetCurrentThread. The access rights granted this thread will be derived from the access rights the impersonated user has to the process. Some access rights including THREAD_SET_THREAD_TOKEN and THREAD_GET_CONTEXT may not be present, leading to unexpected failures.
How to get the main thread ID of a process (known by its ID)?
Can you help me to find the main (only) thread ID of a given by ID process, please ?
Task context: A running process has (at the moment) no windows but a(some) thread(s).
Wanted: Posting of WM_QUIT at the main thread only.
Not-wanted: Using of TerminateProcess or posting WM_QUIT at the non-primary threads.
6 Answers 6
A much simpler and surer way to get the thread id of the main thread is to let the main thread records its own thread id using ::GetCurrentThreadId() into a shared global variable, perhaps in your WinMain or somewhere at the very beginning of your ‘main thread’:
then in your other threads, you can call: ::PostThreadMessage(MainThreadId_G, WM_QUIT, returncode, 0);
I’ve checked how this is handled in MFC, and it looks like UI thread is determined from constructor:
And using MFC call AfxGetApp()->m_nThreadID you can figure out UI thread ID.
However — this approach does not work if .dll was loaded not from main thread — then even MFC’s approach will not work — AfxGetApp()->m_nThreadID will return something else than main thread.
But typically your .dll gets loaded from main thread, but your .dll is not necessary mfc enabled. I’ve could recommend approach like this:
If .dll is loaded by main UI thread, you will get correct thread id from constructor call (GetMainThread class).
Remove AfxGetApp() calls if you don’t need them (In my application I needed those)
Getting the thread ID from a thread
In C# when debugging threads for example, you can see each thread’s ID.
I couldn’t find a way to get that same thread, programmatically. I could not even get the ID of the current thread (in the properties of the Thread.currentThread ).
So, I wonder how does Visual Studio get the IDs of the threads, and is there a way to get the handle of the thread with id 2345 , for example?
11 Answers 11
GetThreadId returns the ID of a given native thread. There are ways to make it work with managed threads, I’m sure, all you need to find is the thread handle and pass it to that function.
GetCurrentThreadId returns the ID of the current thread.
GetCurrentThreadId has been deprecated as of .NET 2.0: the recommended way is the Thread.CurrentThread.ManagedThreadId property.
In C# when debugging threads for example, you can see each thread’s ID.
This will be the Ids of the managed threads. ManagedThreadId is a member of Thread so you can get the Id from any Thread object. This will get you the current ManagedThreadID:
To get an OS thread by its OS thread ID (not ManagedThreadID), you can try a bit of linq.
It seems there is no way to enumerate the managed threads and no relation between ProcessThread and Thread, so getting a managed thread by its Id is a tough one.
For more details on Managed vs Unmanaged threading, see this MSDN article.
You can use the deprecated AppDomain.GetCurrentThreadId to get the ID of the currently running thread. This method uses a PInvoke to the Win32 API method GetCurrentThreadID , and will return the Windows thread ID.
This method is marked as deprecated because the .NET Thread object does not correspond to a single Windows thread, and as such there is no stable ID which can be returned by Windows for a given .NET thread.
See configurator’s answer for more reasons why this is the case.
To get the OS ID use:
An operating-system ThreadId has no fixed relationship to a managed thread, because an unmanaged host can control the relationship between managed and unmanaged threads. Specifically, a sophisticated host can use the CLR Hosting API to schedule many managed threads against the same operating system thread, or to move a managed thread between different operating system threads.
So basically, the Thread object does not necessarily correspond to an OS thread — which is why it doesn’t have the native ID exposed.
For those about to hack:
To find the current thread Id use — `Thread.CurrentThread.ManagedThreadId’. But in this case you might need the current win32 thread id — use pInvoke to get it with this function:
First you’ll need to save the managed thread id and win32 thread id connection — use a dictionary that maps a win32 id to managed thread.
Then to find a thread by it’s id iterate over the process’s thread using Process.GetCurrentProcess().Threads and find the thread with that id:
The offset under Windows 10 is 0x022C (x64-bit-Application) and 0x0160 (x32-bit-Application):
From managed code you have access to instances of the Thread type for each managed thread. Thread encapsulates the concept of an OS thread and as of the current CLR there’s a one-to-one correspondance with managed threads and OS threads. However, this is an implementation detail, that may change in the future.
The ID displayed by Visual Studio is actually the OS thread ID. This is not the same as the managed thread ID as suggested by several replies.
The Thread type does include a private IntPtr member field called DONT_USE_InternalThread , which points to the underlying OS structure. However, as this is really an implementation detail it is not advisable to pursue this IMO. And the name sort of indicates that you shouldn’t rely on this.
View threads in the Visual Studio debugger by using the Threads window (C#, Visual Basic, C++)
In the Threads window, you can examine and work with threads in the application that you’re debugging. For step-by-step guidance on how to use the Threads window, see Walkthrough: Debug by using the Threads window.
Use the Threads window
The Threads window contains a table where each row describes a separate thread in your application. By default, the table lists all the threads in your application, but you can filter the list to show only the threads that interest you. Each column describes a different type of information. You can also hide some columns. If you display all the columns, the following columns appear, from left to right:
Flag: In this unlabeled column, you can mark a thread to which you want to pay special attention. For information about how to flag a thread, see How to: Flag and unflag threads.
Current thread: In this unlabeled column, a yellow arrow indicates the current thread. An arrow outline indicates the current debugger context for a non-current thread.
ID: Displays the identification number for each thread.
Managed ID: Displays the managed identification numbers for managed threads.
Category: Displays the category of threads as either user interface threads, remote procedure call handlers, or worker threads. A special category identifies the main thread of the application.
Name: Identifies each thread by name, if it has one, or as .
Location: Shows where the thread is running. You can expand this location to show the full call stack for the thread.
Priority: An advanced column (hidden by default) that displays the priority or precedence that the system has assigned to each thread.
Affinity Mask: An advanced column (hidden by default) that shows the processor affinity mask for each thread. In a multiprocessor system, the affinity mask determines which processors on which a thread can run.
Suspended Count: An advanced column (hidden by default) that displays the suspended count. This count determines whether a thread can run. For more information about suspended counts, see Freeze and thaw threads.
Process Name: An advanced column (hidden by default) that displays the process to which each thread belongs. The data in this column can be useful when you’re debugging many processes.
Process ID: An advanced column (hidden by default) that displays the process ID to which each thread belongs.
Transport Qualifier: An advanced column (hidden by default) that uniquely identifies the machine to which the debugger is connected.
To display the Threads window in break mode or run mode
- While Visual Studio is in debug mode, select the Debug menu, point to Windows, and then select Threads.
To display or hide a column
- In the toolbar at the top of the Threads window, select Columns. Then, select or clear the name of the column that you want to display or hide.
Display flagged threads
You can flag a thread that you want to give special attention by marking it with an icon in the Threads window. For more information, see How to: Flag and Unflag threads. In the Threads window, you can choose to display all the threads or only the flagged threads.
To display only flagged threads
- Choose Show Flagged Threads Only in the toolbar at the top of the Threads window. (If it’s dimmed, you’ll need to flag some threads first.)
Freeze and thaw threads
When you freeze a thread, the system won’t start execution of the thread even if resources are available.
In native code, you can suspend or resume threads by calling the Windows functions SuspendThread and ResumeThread . Or, call the MFC functions CWinThread::SuspendThread and CWinThread::ResumeThread. If you call SuspendThread or ResumeThread , the suspended count shown in the Threads window will be changed. The suspended count doesn’t change if you freeze or thaw a native thread. A thread can’t execute in native code unless it’s thawed and has a suspended count of zero.
In managed code, the suspended count changes when you freeze or thaw a thread. If you freeze a thread in managed code, its suspended count is 1. When you freeze a thread in native code, its suspended count is 0, unless you used the SuspendThread call.
When you debug a call from native code to managed code, the managed code runs in the same physical thread as the native code that called it. Suspending or freezing the native thread freezes the managed code also.
To freeze or thaw execution of a thread
In the toolbar at the top of the Threads window, select Freeze Threads or Thaw Threads.
This action affects only threads that are selected in the Threads window.
Switch to another thread
A yellow arrow indicates the current thread (and the location of the execution pointer). A green arrow with a curly tail indicates a non-current thread has the current debugger context.
To switch to another thread
Follow either of the following steps:
Double-click any thread.
Right-click a thread and select Switch To Thread.
Group and sort threads
When you group threads, a heading appears in the table for each group. The heading contains a group description, such as Worker Thread or Unflagged Threads, and a tree control. The member threads of each group appear under the group heading. If you want to hide the member threads for a group, use the tree control to collapse the group.
Because grouping takes precedence over sorting, you can group threads by category, for example, and then sort them by ID within each category.
To sort threads
In the toolbar at the top of the Threads window, select the button at the top of any column.
The threads are now sorted by the values in that column.
If you want to reverse the sort order, select the same button again.
Threads that appeared at the top of the list now appear on the bottom.
To group threads
- In the Threads window toolbar, select the Group by list, then select the criteria that you want to group threads by.
To sort threads within groups
In the toolbar at the top of the Threads window, select the Group by list, then select the criteria that you want to group threads by.
In the Threads window, select the button at the top of any column.
The threads are now sorted by the values in that column.
To expand or collapse all groups
- In the toolbar at the top of the Threads window, select Expand groups or Collapse groups.
Search for specific threads
You can search for threads that match a specified string in the Threads window. When you search for threads, the window displays all the threads matching the search string in any column. This information includes the thread location that appears at the top of the call stack in the Location column. By default, the full call stack isn’t searched.
To search for specific threads
In the toolbar at the top of the Threads window, go to the Search box and either:
- Enter a search string and then press Enter.
- Select the drop-down list next to the Search box and select a search string from a previous search.
(Optional) To include the full call stack in your search, select Search Call Stack.
Display thread call stacks and switch between frames
In a multithreaded program, each thread has its own call stack. The Threads window provides a convenient way to view these stacks.
For a visual representation of the call stack for each thread, use the Parallel Stacks window.
To view the call stack of a thread
In the Location column, select the inverted triangle next to the thread location.
The location expands to show the call stack for the thread.