- Home /
Ending a Thread when ending the game
I just created a new thread from within my game. I'm doing it the way I'm used to it in C#
myThread = new Thread(new ThreadStart(myManager.Process));
myThread.Start();
Which works fine so far. Unfortunately I realized after stopping the game in the Editor this thread keeps running. Of course I can't check something like EditorApplication.isPaused from within this thread. So how can I end it? It makes Unity not responding the moment I start the game again. Is there any way to do some multi threading (i.e. not using StartCoroutine)?
Thanks!
Answer by ThePunisher · Dec 09, 2013 at 11:21 PM
Well, I don't necessarily know how to kill a process, BUT! You can have an object in your scene that has its OnDestroy defined, which would contain the logic for killing the thread if it's running. Then have this object DontDestroyOnLoad enabled so it only gets killed when the game stops running.
It's a good suggestion. However, please take note that for example in Windows, you can't guarantee to kill a thread with Thread.Abort (or I may be severely mistaken if you can guarantee that and please let me know because this bugs me too). Thread.Abort is expected to raise a ThreadAbortExcetion on the thread, but other code can ignore it and gobble away (just blindly catching it/executing endlessly in a finally clause). I've found for example that using some .NET classes like NamedPipeClientStream may block and I can't abort the thread if the thread is executing in some method that is blocking. If you can signal Thread.Abort safely, and/or if you have control to set a abort flag that the thread will check sooner rather than later, you should be able to get out of that trap :)
I'm following this thread (no pun intended) as I am currently also wrestling with some issues but related to Editor helper threads that are causing me some annoyance.
Thank you. This is somehow the way I eventually did is. I have a Notification-GameObject which has this method: public void OnApplicationQuit() { Game.instance.StopThreads(); } I know it is somehow still not really great but this way I can smoothly tell all Threads to stop. It even works without Thread.Abort but by setting the while(isRunning) variable to false so the thread closes it's loop. Still, I was hoping for a nicer solution. Thanks anyway!
No problem, sorry I couldn't think of something better. I'm not too familiar with multi-threading :(
Answer by ArkaneX · Dec 10, 2013 at 10:06 AM
I don't know what is the task of this second thread, but I assume it executes this task in a loop. In such case, you can create a class with single bool property which will be used to control this loop, and pass an instance of this class to the new thread. If you want to stop the thread, just set this bool to false. Sample:
public class ThreadingTest : MonoBehaviour {
class ThreadController
{
public bool ShouldExecute { get; set; }
}
private int _testValue = 0;
private ThreadController _threadController;
void Start()
{
_threadController = new ThreadController { ShouldExecute = true };
Thread t = new Thread(RunThread);
t.Start(_threadController);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.X))
{
_threadController.ShouldExecute = false;
}
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log(_testValue);
}
}
void RunThread(object data)
{
var tc = (ThreadController)data;
while (tc.ShouldExecute)
{
Interlocked.Increment(ref _testValue);
Thread.Sleep(1000);
}
}
}
Please note that this is a really trivial example (POC only), not requiring any special constructs (e.g. lock). Even the Interlocked is not required here... In your case, you need to change to false when user exits a game. And to handle it in editor, you probably need EditorApplication.playmodeStateChanged.
Also, I tested this in editor only, but I suggest testing it after build. Especially for mobiles and web player.
Thanks for this suggestion. The problem is much more that there was no general event called for this. I could only access information like EditorApplication.isPaused from within my main thread. But I didn't want the Instance which was "hosting" the thread running in a loop to check this and it didn't get any event "application closes". Looks like the only way was connecting it to a game object and wait for its destruction.
Your answer
Follow this Question
Related Questions
Is it possible to split Texture2D.LoadImage into multiple parts? 1 Answer
How do I run a coroutine in the non-main thread? 1 Answer
Threads? Or just Coroutines? 0 Answers
Does UnityEngine.CustomeYieldInstruction works in a seperate thread? 2 Answers
Why does my EventHandler listener method not finish execution? 1 Answer