2012-04-08 8 views
1

내 첫 번째 게시물이 있지만이 사이트는 과거에 많은 질문에 대답했습니다. 다행히도 필자는 모든 .NET이 내가 만든 스레드를 어떻게 처리하는지 완전히 이해하지 못하기 때문에 직면하게되는 문제를 설명하기에 충분한 세부 정보를 제공 할 수 있기를 바랍니다.System.Threading.Timer가 다른 타이머를 늦추는 원인이됩니다.

그래, 기본적으로 스레드는 비디오 인코더에서 프레임 카운터를 가져 와서 FPS를 계산하는 매 1000ms마다 실행되도록 설정했습니다. 정확성은 System.Threading.Timer로는 충분하지만 현재로서는 정확하지 않습니다 (종종 사건 간 1000ms 이상). 또 다른 Threading.Timer가 실행 중이며 네트워크에서 직렬 장치로 읽는 중입니다. 문제는 네트워크 장치를 사용할 수 없게되고 해당 타이머에서 소켓 시간 초과가 발생하면 FPS 타이머가 완전히 동기화되지 않습니다. 그래서 그들은 이전에 1015ms (측정)마다 실행하고 있었지만,이 다른 Thread.Timer를 시작하여 소켓 연결을 시도하면 FPS 카운터 타이머가 완전히 꺼집니다 (최대 7000ms !!). 왜 이것이 있어야하고 FPS 카운터가 무엇이든 상관없이 1 초에 1 번 실행해야하는 이유는 확실하지 않습니다. 코드의

비트 ->

public Socket mSocket { get; set; } 
public bool Connect(IPAddress ip_address, UInt16 port) 
{ 
    try 
    { 
     mSocket.Connect(ip_address, port); 
    } 
    catch(Exception ex) 
    { 

    } 
    return mSocket.Connected; 
} 
->

FPS 카운터

private void getFPS(Object stateInfo)//Run once per second 
{ 
    int frames = AxisMediaControl.getFrames; //Axis Encoder media control 
    int fps = frames - prevValue; 
    prevValue = frames; 
    setFPSBar(fps, fps_color); //Delegate to update progress bar for FPS 
} 

배터리 잔량 타이머

while (isRunning) 
{ 
    if (!comm.Connected) //comm is standard socket client 
     comm.Connect(this.ip_address, this.port); //Timeout here  causes  other timer threads to go out of sync 

if (comm.Connected) 
{ 
    decimal reading = comm.getBatt_Level(); 
    //Calculate Readings and update GUI 
    Console.Out.WriteLine("Reading = " + (int)prog); 
break;//Debug 

     } 

이 현재 소켓에 연결하는 데 사용되는 코드입니다

희망 너무 모호하지 않은 완전히!

+0

예외를 숨기는 것이 좋은 이유는 무엇입니까? –

+0

소프트웨어는 많은 시간 제한이있는 환경에서 사용되며 매 5 초마다 메시지를 표시하는 것이 유용 할 것이라고 생각하지 않습니다. 나는 디버깅 할 때 예외를 잡았지만 네트워크가 무선이기 때문에 때때로 연결이 실패하고 작동 중에 드롭 아웃이 발생할 것으로 예상한다. 너는 무엇을 제안 하겠는가? – jackocurly0074

+2

나는'TimeoutException' 또는 당신이 염려하는 특정 예외를 포착하고 다른 것들이 전파되도록 허용 할 것을 제안한다. 그렇게하면 다른 예외가 무엇인지 알게됩니다. –

답변

1

FPS 타이머가 7 초 동안 호출되지 않는 이유를 모르겠지만 해결 방법을 제안 할 수 있습니다. Environment.TickCount 값을 기억하여 FPS 값을 마지막으로 업데이트 한 이후로 TimeSpan을 측정하십시오. 그런 다음 FPS 값을 (delta_frames/delta_t)로 계산하십시오.

+0

답장을 보내 주셔서 감사합니다. 나는 그것이 다소 이상하다고 생각한다. 스레드 풀과 관련이 있는지 확실하지 않았다.NET은 전체 응용 프로그램을 테스트 할 때 초당 프레임 수를 세는 약 5 개의 스레드와 배터리 읽기에 대해 4 개가 있습니다. 또한 때때로 소프트웨어는 작업 관리자에서 최대 90 스레드를 사용하는 것처럼 보입니다. 해결 방법은 확실 합니다만 가능한 한 문제의 근원을 찾을 수 있기를 바랍니다! – jackocurly0074

+2

스레드가 너무 많습니다. 타이머 ping이 실행되지 않도록하기 위해 여기에 일부 스레드 풀 한계를 지정했을 수 있습니다. 왜 그렇게 많은 스레드가 있는지 보려면 디버거의 스레드 창을 살펴 보는 것이 좋습니다. Threading.Timer는 스레드를 차단하지 않으므로 이것이 원인이 아닐 수 있습니다. – usr

+0

궁금한 점은, 실행 중에 보면 스레드 클라이언트 중 많은 스레드가 생성 된 것으로 보입니다. 또한 스레드를 사용하여 FPS 카운터의 인터페이스를 업데이트하는 것으로 보입니다. (대리자를 사용합니다.) 인터페이스를 업데이트하는 나쁜 방법입니까? 대리자를 통해 각 타이머가 업데이트 될 때마다 런타임에 여분의 스레드가 추가되는 것으로 보입니다. 따라서 4 개의 비디오 스트림을 볼 때이 문제는 확대됩니다! – jackocurly0074

1

의견을 보내 주셔서 감사합니다. 다음을 수행하여 문제를 해결했습니다.

대신 System.Timers.Timer을 사용하고 자동 재설정을 false로 설정하십시오. 타이머 중 하나가 완료 될 때마다 다시 시작합니다. 이는 각 배터리 장치에 대해 하나의 타이머 만 있다는 것을 의미합니다. 초기 솔루션의 문제점은 네트워크 시간 초과로 인해 스레드가 타이머 간격보다 훨씬 오래 지속되는 것입니다. 따라서 타이머 간격을 맞추기 위해 새 스레드가 더 자주 생성되었습니다.

런타임 중에 이것은 각 배터리 타이머에 대해 약 5-7 개의 스레드가 있음을 의미합니다 (이로 인해 6 개는 시간 초과되고 1 개는 시작될 예정 임). 새 타이머로 변경하면 현재 스레드가 하나만 있어야합니다.

더 높은 정확도를 위해 Stopwatch 기능을 사용하여 (USR에 감사함) 찍은 시간을 기준으로 FPS를 계산하는 코드를 추가했습니다. 도와 주셔서 감사합니다. 예외를 공백으로 두지 않도록해야합니다.

관련 문제