How to pick up a thread when it falls?

1

I have a thread that controls another thread, the problem is that I need the other thread to restart every x time and when I try to start it again I can not make it start.

  

System.Threading.ThreadStateException: 'Thread running or terminated; can not be restarted.'

Is there any way to reuse / restart the thread?

    static void Main(string[] args)
    {
        ThreadStart consola = new ThreadStart(controladorHilos);
        Thread thread = new Thread(consola);

        thread.Start();

    }

Here is where the thread is created , where I get the error. It happens to me so much putting the thread as proceso as putting it with subproceso . The thing is that later I'll need the thread to control more things.

   public static void controladorHilos()
    {
        ThreadStart consola = new ThreadStart(hilo);
        Thread hconsola = new Thread(consola);
        log("se lanza el hilo");

            hconsola.Start()


    }

According to the life cycle of the threads, once the thread ends, there is no way to lift it, is there any alternative to this? Any way for the thread to abort, stop, end, and then get up? It's no good that the thread is paused, it has to start all of 0

The thread method: The thread method opens a socket to an ip address, via telnet, launches several commands and begins to receive information from the socket. What happens is that the session opened on the socket expires every X time or loses connection every X time, the socket does not send me any message that the connection has been lost so that thread continues listening to the socket, even if there is no connection. The socket opens to another headquarters, so I can not think of any better way to solve it.

public static void hilo(){
    byte[] bytes = new Byte[256];
    String data = null;
    TcpClient cliente = new TcpClient();
    while (true)
    {
        NetworkStream stream = cliente.GetStream();
        int i;

        while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
        {
            data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
            Console.WriteLine("Recibido: {0}", data);

            data = data.ToUpper();

            byte[] msg;

            if (data.Contains("login")){

            console.write("login username password");
            //Se abre buffer de datos y empiezo a recibir datos
            }

            if (data.Contains("Cualquier mensaje recibido del socket"))  
            {
                msg = System.Text.Encoding.ASCII.GetBytes("queueinfo" + Environment.NewLine);
                stream.Write(msg, 0, msg.Length);
                //Aqui hay inserciones a una BBDD etc. Todo funciona ok.
            }

        }
    }
}

I have to clarify that in the thread method no error occurs, the error comes from the socket to which this thread points, when the connection is lost with it, it always passes every X time, so, I need to restart all this and I do not know exactly how I could do it.

    
asked by Aritzbn 30.10.2017 в 12:53
source

2 answers

0

In the end I solved the problem with the following, which, really, was what I was looking for.

public static void main(){
    while(true){
        //Creamos el objeto en cada vuelta del bucle
        ThreadStart consola = new ThreadStart(metodo_convertido_en_hilo);
        Thread thread = new Thread(consola);

        thread.Start();
        thread.sleep(1000*60*60); //Para que el hilo se relance cada hora.
        thread.Abort();
    }
 }

With this, what I get is basically to reuse the same thread over and over again, so, in case the thread buffers get caught, the "reinforce", thus achieving the highest ratio between lower redundancy / lower loss of data.

Thanks to the person who was in the chat with me, thanks to that I came up with the solution.

    
answered by 09.11.2017 / 12:30
source
1

I would change the focus to TAP (asynchronous task-based pattern) in order to have a more simplified logic. This involves using the namespace System.Threading.Tasks and the operators async and await :

I'll give you an example (compile it on your computer since the web does not launch well) here: link

We started by changing hilo :

private static void hilo()
{
    byte[] bytes = new Byte[256];
    String data = null;
    TcpClient cliente = new TcpClient();
    NetworkStream stream = cliente.GetStream();
    int i;

    while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
    {
        ...
    }
}

Note that in case of not wanting to return any value we can use void or Task while to return a result we use Task<int> for a int , for example.
Another thing: I eliminated the while (true) .

Then change the "Thread Controller":

// Nota: "async" indica que puede esperar el resultado de una tarea asíncrona
private static async void controladorHilos()
{
    while (true)
    {
        try
        {
            // Aquí "esperamos" a que se complete el hilo.
            await Task.Run(() => Clase.hilo());

            // Este hilo en específico se detendrá a esperar la llamada.
            // Si todo sale bien, lo ejecutará de nuevo y esperará una y otra vez.
        }
        catch(Exception e)
        {
            // Si ocurre un error en el hilo lo capturamos aquí.
            Console.Write("Excepción: " + e.Message);
        }
    }
}

And we invoke it from the Main method:

// Aquí no esperaremos, por lo tanto no necesitamos "async".
public static void Main(string[] args)
{
    // Iniciamos la tarea y nos despreocupamos sin "esperar" (await) el resultado
    Task.Run(() => controladorHilos());
    ...
}
    
answered by 31.10.2017 в 18:21