Убить / прервать определенный поток, используя его идентификатор в C#

Мне нужно прекратить определенный поток, который я уже знаю Id этого, я получаю идентификатор, получая System.Diagnostics.ProcessThreadи я уже обнаружил идентификатор потока, который мне нужен для завершения, что я могу сделать, чтобы завершить его.

1 ответ

Решение

Вы можете сделать это, используя несколько методов P/Invoke. Прежде всего, позвоните OpenThread в потоке с идентификатором, который вы нашли, чтобы получить дескриптор к нему:

IntPtr handle = OpenThread(THREADACCESS_SUSPEND_RESUME, false, (uint)thd.Id);

Тогда позвони SuspendThread используя ручку, которую вы только что получили:

if (handle != IntPtr.Zero)
    var suspended = SuspendThread(threadHandle) == -1

Это приостанавливает поток - т.е. он больше не будет работать. Если вы отчаянно хотите убить его силой, вы можете позвонить TerminateThread на ручке:

TerminateThread(handle, 0); // Or any other exit code.

Обязательно закройте ручку после того, как с ней покончено, например, внутри finally блокировать, если вы оборачиваете его в try / catch.

Как уже упоминалось в комментариях, принудительное завершение потока, как это обычно не то, что вы хотите сделать - будьте очень осторожны при использовании этого. Приостановка потока позволяет вам возобновить его на более позднем этапе. Прекращение немедленно убивает поток (подробнее о том, почему вы не должны прерывать потоки здесь)

Кроме того, в документации MSDN по TerminateThread упоминается следующее:

TerminateThread - опасная функция, которую следует использовать только в самых крайних случаях. Вы должны вызывать TerminateThread только в том случае, если вы точно знаете, что делает целевой поток, и вы контролируете весь код, который, возможно, целевой поток мог выполнять во время завершения.

P / вызывает:

[DllImport("kernel32.dll",SetLastError=true)]
static extern int SuspendThread(IntPtr hThread);

[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle,
   uint dwThreadId);

[DllImport("kernel32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);

[DllImport("kernel32.dll")]
static extern bool TerminateThread(IntPtr hThread, uint dwExitCode);
Другие вопросы по тегам