Тема вышла - PullRequest
       13

Тема вышла

1 голос
/ 31 января 2012

У меня есть небольшая проблема с темой. Я выполняю функцию Receive с тайм-аутом, установленным на 600, но он заканчивается здесь

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;
}

Функция должна заканчиваться там, только если поток закончен, и я получил все данные, но когда я открываю файл errores.txt, я вижу, что значение ThreadState равно Running или WaitSleepJoin.

Есть идеи, почему функция прерывается?

Больше кода ниже ->

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;
    }
  }

Ответы [ 2 ]

4 голосов
/ 31 января 2012

Возможно, что значение свойства ThreadState изменяется во время оценки этого кода:

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;
}

Рассмотрим следующий сценарий:

  1. thr.ThreadState - это WaitSleepJoin
  2. первая часть оператора if оценивается как true
  3. thr.ThreadState изменяется на Running до оценки второй части if
  4. вторая часть оператора if оценивается как true
  5. , поскольку обе части оцениваются как true, вводится блок if

Вы можете попробовать переписать код, как показано ниже, так что вы проверяете значение свойства ThreadState только один раз:

var state = thr.ThreadState;
if (state != ThreadState.Running && state != ThreadState.WaitSleepJoin)
{
    lg.WriteString("EXIT BY THREAD END");
    lg.WriteString("LAST: "+ state.ToString());
    break;
}
2 голосов
/ 31 января 2012

Я заметил некоторые примечания для свойства ThreadState от Microsoft:
http://msdn.microsoft.com/en-us/library/system.threading.thread.threadstate.aspx

В частности, указывается, что:

Состояние потока представляет интерес только в сценариях отладки. Ваш код никогда не следует использовать состояние потока для синхронизации действий резьб.

Хотите использовать объект Monitor или Mutex?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...