0

I am trying to end my Thread, within the thread, and when aborted, i want to detect that the thread has been aborted (or just, stopped really)

This is what i am doing to do that, but isnt working as it never gets to this part

if (!thread.IsAlive){
   CommandPrompt.SayMessage("Oops! MBP thread died.");
}

This is how i'm going about it, thank you for the help. sorry if my question is confusing please ask questions so i can help you help me :) thanks!

public static Thread thread;
        public static void 1()
        {
            thread = new Thread(thread1);
            thread.Start();
            if (!thread.IsAlive)
            {
                CommandPrompt.SayMessage("Oops! MBP thread died.");
            }
        }
        public static void thread1()
        {
            {
             int test = 0;
             while (thread.IsAlive){
                 Console.WriteLine("running.."); // this text will be displayed when the thread is active, and will stop when stopped.
                 Thread.Sleep(2500);
                 test += 1;
                 if (test > 4) // after 4 loops, i want the thread to end itself
                     thread.Abort();
             }
             if (!thread.IsAlive){ // once the thread is ended i want it to tell us that, but it never gets to this part.
                 CommandPrompt.SayMessage("Oops! MBP thread died.");
             }

            }
        }
Moog
  • 107
  • 1
  • 3
  • 11
  • well, you are calling `thread.Abort()` which according to the [docs](https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.abort?view=net-6.0) "*Raises a ThreadAbortException in the thread on which it's invoked*". So, you raise an exception you don't catch, thus the code after the exception isn't executed anymore. In fact, that's the whole point of aborting a thread, isn't it? – derpirscher Jun 10 '22 at 19:14
  • The thread you abort is the one running the code that waits to see if the thread is alive. Of course you won't "get to this part": you've aborted the execution of that code. – StriplingWarrior Jun 10 '22 at 19:15
  • You really might want to consider switching to Tasks with CancellationTokens instead. That way you can easily observe the behavior externally to the work itself, and then cooperatively cancel it. – David L Jun 10 '22 at 19:16
  • Aborting threads is generally a Bad Idea. Why have you chosen this approach? Why not just `return;`, for example? – StriplingWarrior Jun 10 '22 at 19:16
  • And depending on the environment you are running this, you also might end up in [this situation](https://stackoverflow.com/questions/7225007/security-exception-with-thread-abort) – derpirscher Jun 10 '22 at 19:16
  • Whatever you're attempting to do, using explicit threads is almost certainly the wrong thing to use. You'll spend a lot of time focusing on *mechanisms* rather than useful work - and in fact all of the code you're showing us is just mechanisms. – Damien_The_Unbeliever Jun 10 '22 at 19:17
  • @StriplingWarrior Aborting *the thread running the code* is a big exception to that. Because you're not throwing an exception at an arbitrary point in code. Aborting the current thread is no more dangerous than just explicitly throwing a normal exception. – Servy Jun 10 '22 at 19:17
  • It was more, in the case something terminated the thread, whether thats someone trying to crack my softwares security or whatever it is, I want it to capture the thread being aborted/terminated. – Moog Jun 10 '22 at 19:19
  • Ah just noticed: You have the exact same piece of code twice in your code. Which is the one, you think you should reach, but don't? The first or the second? If it's the first one, it's obvious, because that part of the code has been executed a long time before the thread got aborted ... And if it's the second one, it's also quite obvious, because, well, you aborted the thread ... – derpirscher Jun 10 '22 at 19:20
  • 1() Is just to start the thread. i want the " if (!thread.IsAlive){" part to run once the thread has been terminated/aborted in whatever way it got terminated or aborted. i wont be making the thread purposely killed, i just want to detect it IF it does happen – Moog Jun 10 '22 at 19:23
  • But in fact you ARE KILLING your thread after 4 iterations of the loop, because you call `thread.Abort()`. And once your thread was aborted (doesn't matter if by some code running inside the thread or outside) the rest of the code in the thread isn't executed anymore. You you cannot check if the thread was killed from within the thread ... – derpirscher Jun 10 '22 at 19:28
  • im aware im killing it, it was just to reproduce the affect of the thread being killed. how else can i check the thread has been killed elsewise? make a while loop that checks every so often to see if the thread is still alive in 1()? – Moog Jun 10 '22 at 19:30
  • 1
    So if you are aware you killed it, why do you wonder, the code in the end doesn't get executed. `thread.IsAlive` will always be `true` if it's called from within the thread. So it's pointless using it there. Maybe if you post your real usecase and not something you madeup, it will make more sense and we could help you better – derpirscher Jun 10 '22 at 19:30
  • my use case is to detect if a thread has been aborted/terminated. i had .Abort() there to reproduce the effect of someone else trying to kill my thread. i just want to detect if that has been done or not. if a third part has killed my thread, i want a check to see if its still alive or not. the original thread in my actual code just has a foreach that checks processes by name that are able to tamper with my program (e.g de4dot, megadumper, dnspy). i had just shortened it down to the parts that mattered so it was easier than having unneeded code that didnt relate to what i needed. – Moog Jun 10 '22 at 19:35
  • Using Thread.Abort() is _such a bad idea_ that [it is considered obsolete](https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/thread-abort-obsolete). The .NET Core Platform (at least as of 3.1, possibly sooner), calling it will throw a `PlatformNotSupportedException`, regardless of which thread it's called from. – StriplingWarrior Jun 10 '22 at 19:42
  • @Moog If other processes are going to mess with your application, there's no reliable way for you to do anything about it: those processes can just mess with the code that tries to detect the issue, or they could pause the thread rather than killing it, or they could kill your entire process rather than just that one thread. – StriplingWarrior Jun 10 '22 at 19:49
  • You might find this interesting: [What's wrong with using Thread.Abort()](https://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort). Be aware that the `Thread.Abort` method is not supported on the .NET Core and later platforms. – Theodor Zoulias Jun 10 '22 at 22:42
  • Calling `thread.Abort();` can cause a run-time corruption. Don't ever use it, except when you are trying to crash out of your entire app. – Enigmativity Jun 10 '22 at 22:59

1 Answers1

1

If you want to check if a thread is still alive, you cannot do that from the code running in that particular thread. Because, if you can execute the code to check if the thread is still alive, it is -- obviously -- still alive. And if the thread is not alive anymore it will -- obviously -- not be able to execute any more code ...

So the only way is to do this from somewhere outside the thread (ie some other thread, maybe even the main thread).

Just schematic code, which is rather clumsy, but will give you a first idea of how you can address this issue. But if there is a third party messing around with your threads, that won't help anything, because what prevents them from killing off your whole application?

public class ThreadTest {

  static bool ranToEnd = false;

  public static void Main(){
    var thread = new Thread(aThread);
    var lc = 1;
    thread.Start();

    while (true){  
      if (!aThread.IsAlive) {
        if (ranToEnd)
          Console.WriteLine("aThread terminated normally");
        else
          Console.WriteLine("aThread ended prematurely");

        break;
      } else if (++lc == 10) {
        aThread.Abort(); //Simulating the abortion of the thread
      }
      Thread.Sleep(1000);
    }
  }

  public static void aThread() {
    //do some work in this thread

    // if the thread ran to an end normally, this will be set to true
    // if the thread ended prematurely, this will stay false ... 
    ranToEnd = true;
  }

}
derpirscher
  • 14,418
  • 3
  • 18
  • 35