This code freezes UNITY!

When i press play button on unity, this works like diamonds. But when i press play second time unity freezes, could threads cause this?

import System;
import System.IO;
import System.Net;
import System.Net.Sockets;
import System.Text;
import System.Threading;


var server  : TcpListener; 
var client  : TcpClient;
var stream  : NetworkStream;
var reader  : StreamReader;
var writer  : StreamWriter;
var msg     : String;
var thread = Thread(Parse);
var UniqueHash : String;
var Running : boolean;

function Start(){
DontDestroyOnLoad(this);
}

function Update(){
if(Var.State == 1){
        client = new TcpClient("127.0.0.1", 6112);
        stream = client.GetStream();    
        reader = new StreamReader(stream);
        writer = new StreamWriter(stream);
        Running = true;
        thread.IsBackground = true;
        thread.Start();
        Var.State = 2;
    }
    
}

function OnApplicationQuit()
{
Running = false;
thread.Join(500);
Debug.Log("Thread Terminated");
}

function Send(data : String){
stream = client.GetStream();
writer.WriteLine(data);
writer.Flush();

}


function Parse()
{ 
try{
while(Running){
	stream = client.GetStream();
if(stream.DataAvailable){
    msg = reader.ReadLine();
    
	        if (msg == null){}
	        else
	        {
	            HandleMessage(msg);
	            msg = "";
	        }
    }
    else {
    Thread.Sleep(100);
    }
 }
}
catch (ThreadAbortException)
    {
        print("exception");
    }
}




function HandleMessage(data : String){

var Header : String;

Header = data.Substring(0,4);

        switch (Header){

            case "0x00" : onPacket0x00(data);
            break;

            case "0x01" : onPacket0x01(data);
            break;

        default:
        print ("Unparsed packet: " + Header + " Data: " + data);
        break;

    }
    data = "";
    Header = "";

}

 

function onPacket0x00(data : String) {
Var.State = 3;
UniqueHash = data.Substring(4,data.Length - 4);
Debug.Log("Connected! Hash: " + UniqueHash); 
Send("0x01" + UniqueHash + "/" + Var.Username + "/" + Var.Password);
}

 

function onPacket0x01(data : String) {
Debug.Log("Login code: " + data.Substring(4,1));
}

Yea, sounds like you aren’t properly shutting down the extra thread. Even if you ask it to stop, if you’ve pushed to long a queue of “work” it’ll hang Unity until the thread finishes that work (upon a second play).

I suggest using a “work queue” and pushing only appropriate sized work loads to the extra thread each frame - then make sure you’re cleaning up that thread on application quit. The combination of these should keep things working well with extra threads.

Can you show me some pseudo code so i get some logic behind this? :slight_smile:

Sure. Personally, I use a combination of three classes. A priority queue class, a thread safe queue class, and a thread wrapper class.

The thread safe queue I use is virtually identical to Marc Gravell’s answer here:

The priority queue I use is:

Then for the thread wrapper, it pretty much looks like this:

public class WorkThread
{
    ThreadQueue<Action> _work;
    bool _stop;
    Thread _thread;
    
    public WorkThread(){
        _work = new ThreadQueue<Action>();
    }
    
    public void AddWork(Action work){
        _work.Enqueue(work);
    }
    
    public void StartThread(){
        _stop = false;
        _thread = new Thread(new ThreadStart(ExecuteThread));
        _thread.IsBackground = true;
        _thread.Priority = ThreadPriority.BelowNormal;
        _thread.Name = "Work Thread";
        _thread.Start();
    }
    public void StopThread(){
        _stop = true;
    }
    
    void ExecuteThread(){
        while (!_stop){
            if (_work.Count > 0){
                try{
                    Action action;
                    if (_work.TryDequeue(out action)){
                        action();
                    }
                } catch (Exception e){
                    Debug.LogError("Exception in work thread: " + e);
                }
            }
            continue;
        }
    }
}

Strictly speaking the PriorityQueue isn’t necessary depending on your project. However, I find it super helpful so that I can use this workflow:

Step 1:
Unity Thread - find any work I should be doing that isn’t currently queued, add it to the priority queue with an appropriate priority (priority queue baby)
Unity Thread - queue up a reasonable amount of work to the work thread (this is not a priority queue, only a straight FIFO queue - the ThreadQueue)

Work Thread - Chew through my queue of Actions as fast as possible.

(note: above code not tested, just a quick type up - but may just work)

Still having problems with this… How i do that in Javascript?

I got it working. I modified first post code :slight_smile: