2011-01-08 4 views
1

지금은 하루 종일이 문제로 차단되었지만 수천 개의 Google 결과를 읽었지만 아무 것도 내 문제를 반영하지 않거나 가까이에 와서 보이지 않습니다. 당신은 나를 위해 바른 방향으로 밀어 넣습니다.StackOverFlowException -하지만 우연히 NO 재귀/무한 루프

클라이언트는 자신의 시스템에 대한 데이터와 스크린 샷을 수집하고 XML 스트림 (이 그림을 바이트 []으로 그림)으로 직렬화합니다. 배열]) 이것을 정기적 인 간격으로 서버에 보냅니다. 서버는 (tcp를 통해) 스트림을 수신하고 xml을 정보 객체로 직렬화 해제하고 정보를 Windows 양식에 표시합니다. 이 프로세스는 3 초의 제출 간격으로 약 20-25 분 동안 안정적으로 실행됩니다. 메모리 사용량을 관찰 할 때 아무런 의미가 없으며 다소 안정적입니다. 그러나이 20-25 분 후에 서버는 tcp-stream을 deserialize하는 지점에서 StackOverflowException을 던집니다. 특히 byte [] - 배열에서 Image 속성을 설정할 때 그렇습니다.

나는 반복적 또는 무한 루프를 철저히 수색했으며, 수천 개의 sucessfull 간격 후에 발생한다는 사실에 관해서는 거의 상상할 수 없었다.

public byte[] ImageBase 
    { 
     get 
     { 
      MemoryStream ms = new MemoryStream(); 
      _screen.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 
      return ms.GetBuffer(); 
     } 
     set 
     { 
      if (_screen != null) _screen.Dispose(); //preventing well-known image memory leak 
      MemoryStream ms = new MemoryStream(value); 
      try 
      { 
       _screen = Image.FromStream(ms); //<< EXCEPTION THROWING HERE 
      } 
      catch (StackOverflowException ex) //thx to new CLR management this wont work anymore -.- 
      { 
       Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); 
      } 
      ms.Dispose(); 
      ms = null; 
     } 
    } 

내가 더 많은 코드가 불필요한 것, 또는 매우 복잡한 얻을 수 있기를 바랍니다 ...

도와주세요, 난 전혀 실마리 더 이상

들으이 없습니다 크리스

+0

_screen = Image.FromStream (ms)에서 수행하는 작업에 궁금한 점이 있습니까? 아마 실수로 ImageBase를 설정하고 계신 것 같습니까? – Trap

+5

나는 SO 질문을 좋아합니다. – Mehrdad

+0

당신은 실제로 각 MemoryStream의 사용법을 using() - 블록에 넣어야합니다. 그러면 정확하게 처리되는 것을 쉽게 볼 수 있습니다! –

답변

3

내가 게시 한 코드가 아니라 스택을 확장하는 TCP 스트림에서 읽는 코드가 아닌 것 같습니다. Image.FromStream 동안 낙타의 등을 돌리는 짚이 일어난다는 사실은 아마 무의미합니다. 사람들이 자기 호출 코드 (때로 간접적으로 A -> B -> A -> B와 같은)를 포함하는 소켓 처리 코드를 작성하는 경우가 종종 있습니다. 그 코드를 검사하고 여기에 게시하여 보도록하십시오.

+0

아, 예외 세부 정보를 살펴보면 오버플로시 호출 스택이 어떻게 보이는지 확인할 수 있습니다. – Jacob

+0

여기 있습니다 ... Listen() - Answer() - Listen() - Answer()가 재귀 적으로 호출되었습니다 .- 어제 이미 이것을 찾았으나 여기를 '해결'하는 것을 잊었습니다. 하지만 고마워 너의 도움을 위해 tho;) – tunefish

3

이것을 읽으십시오. Loading an image from a stream without keeping the stream open

스택 또는 스택을 부는 다른 개체에서 스트림이 유지 관리되는 것으로 보일 수 있습니다.

내 제안은 단지 byte[]을 잡고 가능한 한 마지막 순간까지 기다렸다가 디코딩하고 그립니다. 즉시 이미지를 처리하십시오. 당신의 get/set은 단지 byte[]을 설정/가져올 것입니다. 그런 다음 현재 byte[]을 디코딩 할 사용자 지정 드로잉 루틴을 구현하고 필요한 것 이상의 리소스를 보유하지 않도록 그립니다.

업데이트

당신이 우리에게 더 도움을 줄 수 있습니다 전체 스택 추적을 얻을 수있는 방법이 있다면. 나는 그것이 내가 설명한 것처럼 문제가 아니라고 생각하기 시작했다. 세터에서하는 것처럼 10,000 개의 이미지를 생성 한 샘플 프로그램을 만들었지 만 문제는 없었습니다. 3 초마다 이미지를 보내면 분당 30 장, 20 분 분당 600 장입니다.

저는이 문제에 대한 해결책에 관심이 많습니다. 나는 나중에 다시 돌아올거야.

그러나 원격지에는 몇 가지 가능성이 있습니다.

  • Image.FromStream은 유효하지 않은/손상된 바이트 []를 처리하려고 시도하며 그 방법은 재귀를 사용하여 비트 맵을 디코딩합니다. 매우 희박합니다.
  • 예외가 있다고 생각되는 곳에서는 예외가 발생하지 않습니다. 가능한 경우 전체 스택 추적이 매우 유용합니다. 당신이 말했듯이 당신은 StackOverflowException을 잡을 수 없다. 비록 당신이 디버거를 통해 그것을 실행하는 경우이 조항이 있다고 생각합니다.
+0

또한 이것은 반드시 원인이 될 필요는 없습니다. "getter"의 MemoryStream은 IDisposable이므로 처리해야합니다. –

+0

@Dave 좋은 전화 나는 그 것을 놓쳤다. 만약 그가 바이트 []를 붙잡고 있다면, 아마도 할당 문제의 대부분을 줄일 수 있기를 바랍니다. –

1

Image.FromStream에 대한 MSDN 설명서는 과 관련이 있는지 확실하지 않습니다. 이미지 수명 동안 스트림을 열어 놓아야합니다.

+0

아니, 난 그것을 열어 두지 않을거야;) 그것은 매력처럼 지금 작동;) – tunefish