2012-01-31 4 views
1

У меня есть небольшая проблема с Thread. Я исполняю функции 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

'Thread.Sleep's is not good idea –

+0

И что я должен использовать для расчета времени выполнения потока? – Sinjuice

+3

для основных целей, System.Diagnostics.Stopwatch можно использовать как точный таймер. –

ответ

4

Это может быть возможно, что значение 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; 
} 
+0

var state = thr.ThreadState; сделал вещь работа. Благодарю. – Sinjuice

+0

Прохладный, рад, что я мог бы помочь. – rsbarro

2

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

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

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

Вы хотите изучить вместо этого объект Monitor или Mutex?

+0

Я не знал. Но мьютекс не очень помог мне с моей задачей, но пока я искал ее, я обнаружил, что могу подождать, пока поток завершится с помощью функции Join. – Sinjuice

Смежные вопросы