2013-05-09 6 views
0

Я пытаюсь контролировать часть тестового оборудования, и мне нужно, чтобы последовательность была правильной, как я общаюсь с ней.Почему эта нить никогда не заканчивается?

Сначала я звоню StartGettingTraceData(). Затем некоторое время в будущем я вызываю StopGettingTraceData(), чтобы попытаться закончить функцию GetTraceData() вместо ее повторного запуска. Но НИКОГДА не бывает. На самом деле, я никогда не добираюсь до линии DoneTraces.Set(), поэтому на линии bool timedOut = !DoneTraces.WaitOne(10000), timedOut всегда верно;

private static AutoResetEvent DoneTraces = new AutoResetEvent(false); 

private void GetTraceData() 
{ 
    byte[] receivedbytes = new byte[1]; 
    if (Connection.ReadData(receivedbytes) && receivedbytes[0] == 192) 
     ProcessIncomingTrace(); 

    Thread.Sleep(100); 

    if (RunTraceQueryWorker) 
     new Thread(GetTraceData).Start(); 
    else 
    { 
     Thread.Sleep(200); 
     DoneTraces.Set(); 
    } 
} 

private void StartGettingTraceData() 
{ 
    RunTraceQueryWorker = true; 
    new Thread(GetTraceData).Start(); 
} 

private bool StopGettingTraceData() 
{ 
    RunTraceQueryWorker = false; 
    bool timedOut = !DoneTraces.WaitOne(10000); 
    return timedOut; 
} 

Любые мысли о том, что происходит?

EDIT:

Вот моя функция Connection.ReadData (...). Кстати, это серийное соединение.

public bool ReadData(byte[] responseBytes) 
{ 
    int bytesExpected = responseBytes.Length, offset = 0, bytesRead; 
    while (bytesExpected > 0 && (bytesRead = MySerialPort.Read(responseBytes, offset, bytesExpected)) > 0) 
    { 
     offset += bytesRead; 
     bytesExpected -= bytesRead; 
    } 
    return bytesExpected == 0; 
} 
+1

Нитки дорогостоящие, поэтому вы не должны создавать их рекурсивно. У вас так много потоков (выполнение 'Sleep()'), вероятно, также является вашей проблемой без остановки. –

+0

Вы пытались использовать обработчик DataReceived Event? Вчера вечером я смотрел руководство, и это кажется довольно прямым, за исключением различных ответов, которые возможны. – dbasnett

ответ

1

Вместо recusively повторного вызова GetTraceData, вы должны использовать цикл, глядя на ваше состояние, как это:

private static AutoResetEvent DoneTraces = new AutoResetEvent(false); 

private void GetTraceData() 
{ 
    do 
{ 
    byte[] receivedbytes = new byte[1]; 
    if (Connection.ReadData(receivedbytes) && receivedbytes[0] == 192) 
     ProcessIncomingTrace(); 

    Thread.Sleep(100); 
} 
while (RunTraceQueryWorker) 

Thread.Sleep(200); 
DoneTraces.Set(); 

} 

private void StartGettingTraceData() 
{ 
    RunTraceQueryWorker = true; 
    new Thread(GetTraceData).Start(); 
} 

private bool StopGettingTraceData() 
{ 
    RunTraceQueryWorker = false; 
    bool timedOut = !DoneTraces.WaitOne(10000); 
    return timedOut; 
} 

Это невозможно знать конкретно, почему ваш код замерзает без понимания того, что такое ReadData & ProcessIncomingTrace() делать.

+0

Вы правы. Все отлично работает, когда я комментирую эти две строки кода. У меня должны быть другие проблемы. –

+0

Если вы положили точку останова в вызов ReadData(), вы когда-нибудь видели его возвращение? – Chris

+0

Я решил использовать код, очень похожий на ваш (do while loop). Решите мою проблему, я должен был направить функцию «ProcessIncomingTrace()». Сейчас работает как шарм. –

0

Ну, есть вероятность, что ReadData вызов блокируется. В стороне, вы делаете это трудно на себя со всей этой рекурсивной резьбой ... Разве вы не можете использовать цикл?

private void GetTraceData() 
{ 
    byte[] receivedbytes = new byte[1]; 

    while(RunTraceQueryWorker) 
    { 
     if(Connection.ReadData(receivedbytes) && receivedbytes[0] == 192) 
     { 
      ProcessIncomingTrace(); 
     } 
     Sleep(100); 
    } 

    Thread.Sleep(200); 
    DoneTraces.Set(); 
} 
Смежные вопросы