2011-01-08 76 views
1

我現在被這個問題阻塞了整整一天,閱讀了成千上萬的谷歌搜索結果,但似乎沒有反映我的問題,甚至接近它...我希望任何你對我有一個正確的方向。我寫了一個客戶端 - 服務器應用程序(所以更像2個應用程序) - 客戶端收集有關他的系統的數據以及屏幕截圖,將所有這些數據序列化爲一個XML流(圖片爲byte [] - 數組]]並將其定期發送到服務器。 服務器接收流(通過tcp),將xml反序列化爲一個信息對象並在Windows窗體上顯示信息。 此過程以3秒的提交間隔穩定運行約20-25分鐘。當觀察內存使用情況時,沒有什麼重要的東西可以看到,也有點穩定。但是在這20-25分鐘後,服務器在反序列化tcp-stream的位置拋出StackOverflowException異常,尤其是在設置byte [] - 數組的Image屬性時。StackOverFlowException - 但很明顯沒有遞歸/無限循環

我徹底搜查了遞歸或無限循環,以及關於它歷經千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; 
     } 
    } 

我希望有更多的代碼是不必要的,或者它可能變得非常複雜...

請幫幫忙,我不知道在所有的再

THX 克里斯

+0

我不知道你在_screen = Image.FromStream(ms)中做了什麼,也許你是在不經意間設置ImageBase? – Trap 2011-01-08 03:15:59

+5

我喜歡SO的SO問題。 – Mehrdad 2011-01-08 03:18:51

+0

你真的應該把每個MemoryStream的用法放到一個using()塊中,這樣可以更容易地看到正確的處理方式! – 2011-01-08 03:35:22

回答

3

我懷疑這不是您發佈的代碼,而是從正在增長堆棧的TCP流中讀取的代碼。在Image.FromStream期間發生的破秸稈背的事實可能是無關緊要的。我經常看到人們編寫包含自我調用代碼的套接字處理代碼(有時間接地,如A→B→A→B)。您應該檢查該代碼並將其發佈到此處供我們查看。

3

你可能想讀這個。 Loading an image from a stream without keeping the stream open

看起來有可能在堆棧或其他某個最終會堆棧的對象上維護流。

我的建議是,然後只是堅持byte[],並等到最後一刻解碼並繪製它。然後立即處理該圖像。您的獲得/設置將會設置/獲得byte[]。然後,您將實現一個自定義繪圖例程,該例程將解碼當前的byte[]並繪製它,以確保不會超出必要的任何其他資源。

更新

如果有一種方法可以讓我們,我們也許能夠進一步幫助一個完整的堆棧跟蹤。我開始認爲這不是我所描述的問題。我創建了一個示例程序,可以創建10,000張圖像,就像您在二傳手中一樣,並且沒有問題。如果每3秒發送一張圖像,那麼每分鐘30張圖像就是20分鐘,這隻有600張圖像。

我對這個解決方案非常感興趣。我稍後再回來。

但是,有一些可能性,遠程。

  • Image.FromStream嘗試處理無效/損壞的字節[],該方法以某種方式使用遞歸來解碼位圖。不大可能。
  • 異常不會被拋出,你認爲它是。如果可能,完整的堆棧跟蹤將非常有用。正如你所說你無法捕捉到StackOverflowException。如果你通過調試器運行它,我相信有這方面的規定。
1

我不確定它是否相關,但是Image.FromStream的MSDN文檔指出 您必須在圖像的生命週期中保持該流的打開狀態。