Sinjuice
Sinjuice

Reputation: 562

Thread is quitting

I have a little problem with a Thread. I execute the function Receive with time-out set to 600, but it ends here

if ((thr.ThreadState != ThreadState.Running) 
    && (thr.ThreadState != ThreadState.WaitSleepJoin))
{
  ThreadState st = thr.ThreadState;
  lg.WriteString("EXIT BY THREAD END");
  lg.WriteString("LAST: "+st.ToString());
  break;
}

The function should end there only if the thread is over and I have received all the data, but when I open the file errores.txt I see that the ThreadState value is Running or WaitSleepJoin.

Any idea why the function is aborting?

More code below ->

bool exit = false;
void WaitAndRead() {
if (buffer == null)
  buffer = new List<byte>();
buffer.Clear();
try
{
  while (sock_client.Available < 1 && !exit)
    Thread.Sleep(10);
  while (sock_client.Available > 0 && !exit)
  {
    byte[] b = new byte[sock_client.Available];
    sock_client.Receive(b, 0, b.Length, SocketFlags.None);
    buffer.AddRange(b);
    Thread.Sleep(25);
  }
}
catch (Exception ex) 
{ 
  Log lg = new Log("C:\\TPV\\errores.txt"); 
  lg.WriteException(ex, true); 
}

public int Receive(int timeout,out List<byte> result) 
{
  result = new List<byte>();
  try
  {
    if (!Connected)
      return NOT_CONNECTED;
    bool ok = true;
    ThreadStart str = delegate 
    {
      try { WaitAndRead(); }
      catch (Exception ex) 
      { 
        Log lg = new Log("C:\\TPV\\errores.txt"); 
        lg.WriteException(ex, true); ok = false; }
      };
      exit = false;
      Thread thr = new Thread(str);
      thr.Start();
      int x = 0;
      int max = 10 * timeout;
      while (x < max)
      {
        Log lg = new Log("C:\\TPV\\errores.txt");
        if ((thr.ThreadState != ThreadState.Running) 
            && (thr.ThreadState != ThreadState.WaitSleepJoin))
        {
          ThreadState st = thr.ThreadState;
          lg.WriteString("EXIT BY THREAD END");
          lg.WriteString("LAST: "+st.ToString());
          break;
        }
        x++;
        Thread.Sleep(10);
      }
      exit = true;
      if (x >= max)
        return Timeout;
      result = new List<byte>(buffer.ToArray());
      return ok?OK:NOT_CONNECTED;
    }
    catch(Exception ex) 
    {
      Log lg = new Log("C:\\TPV\\errores.txt"); 
      lg.WriteException(ex, true);
      return NOT_CONNECTED;
    }
  }

Upvotes: 1

Views: 197

Answers (2)

Lindsay Morsillo
Lindsay Morsillo

Reputation: 530

I noticed some of the notes for the ThreadState property from Microsoft:
http://msdn.microsoft.com/en-us/library/system.threading.thread.threadstate.aspx

In particular, it points out that:

Thread state is only of interest in debugging scenarios. Your code should never use thread state to synchronize the activities of threads.

Do you want to look into using a Monitor or Mutex object instead?

Upvotes: 2

rsbarro
rsbarro

Reputation: 27369

It may be possible that the value of the ThreadState property is changing while this code is evaluating:

if ((thr.ThreadState != ThreadState.Running) && (thr.ThreadState != ThreadState.WaitSleepJoin))
{
    ThreadState st = thr.ThreadState;
    lg.WriteString("EXIT BY THREAD END");
    lg.WriteString("LAST: "+st.ToString());
    break;
}

Consider the following scenario:

  1. thr.ThreadState is WaitSleepJoin
  2. first part of if statement evaluates to true
  3. thr.ThreadState changes to Running before second part of if is evaluated
  4. second part of if statement evaluates to true
  5. since both parts evaluated to true, the if block is entered

You could try rewriting the code as shown below so you are only checking the value of the ThreadState property once:

var state = thr.ThreadState;
if (state != ThreadState.Running && state != ThreadState.WaitSleepJoin)
{
    lg.WriteString("EXIT BY THREAD END");
    lg.WriteString("LAST: "+ state.ToString());
    break;
}

Upvotes: 4

Related Questions