Well, the first necessary thing you’re already doing, which is to save the Managedthreadid.
For the user to abort, you also need to save the list to show only his, but that’s not what the question is about.
The first step is to import the DLL kernel32.dll and use to open and end Thread by Managedthreadid. Would look like this:
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern bool TerminateThread(IntPtr hThread, uint dwExitCode);
After that, just finish the selected Thread, this way:
IntPtr ptrThread = OpenThread(1, false, (uint)id);
TerminateThread(ptrThread, 1);
See a full example in the code below:
class Program
{
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern bool TerminateThread(IntPtr hThread, uint dwExitCode);
static void Main(string[] args)
{
Console.Out.WriteLine("Forking off threads...");
for (int i = 0; i < 5; i++)
{
Thread t = new Thread(new ThreadStart(RunInfinite));
Console.Out.WriteLine("Thread " + t.Name + "(ManagedThreadId: " + t.ManagedThreadId + ") created!");
}
ProcessThreadCollection processThreads = Process.GetCurrentProcess().Threads;
Console.Out.WriteLine("=> Total threads: " + processThreads.Count);
foreach (ProcessThread pt in processThreads)
{
int timerSeconds = 5;
while (timerSeconds-- > 0)
{
Console.Out.Write("\r Seconds before thread " + pt.Id + " dies: " + timerSeconds);
System.Threading.Thread.Sleep(1000);
}
IntPtr ptrThread = OpenThread(1, false, (uint)pt.Id);
if (AppDomain.GetCurrentThreadId() != pt.Id)
{
try
{
TerminateThread(ptrThread, 1);
Console.Out.Write(". Thread killed.\n");
}
catch (Exception e)
{
Console.Out.WriteLine(e.ToString());
}
}
else
Console.Out.Write(". Not killing... It's the current thread!\n");
}
Console.Out.WriteLine("=> Total threads now: " + Process.GetCurrentProcess().Threads.Count);
Console.ReadLine();
}
public static void RunInfinite()
{
while (true)
{
System.Threading.Thread.Sleep(10000);
}
}
}
Another way would be the same this answer, where you would search for threads and check if the id is the same, but this way I wouldn’t advise much, because from what I said, will have many threads in your system.
public void KillThread(int index)
{
string id = string.Format("MyThread{0}",index);
foreach (Thread thread in _threads)
{
if (thread.Name == id)
thread.Abort();
}
}
References:
Kind of dangerous, but if you do, you can create a Singleton class that has a thread list with user identification, then you can access from any part of the system, could filter by user finish and etc. I would use Task, is more current, and better adapts to various situations, besides having the Continuewith method, with it you can put an action for when the task ends, as remove it from the list for example.
– FBatista