2011-03-22 40 views
0

我正在努力處理關閉時窗口窗體有時拋出的ObjectDisposedException。在我的客戶端 - 服務器應用程序中,客戶端會捕獲屏幕截圖,然後通過TCP/IP在服務器上發送更新表單的屏幕截圖。此表單關閉時出現問題。ObjectDisposedException引發的表單

下面是在服務器代碼:

// here the bytes of the screenshot are received 

public void appendToMemoryStream(byte[] data, int offset) 
     { 
      if (!ms.CanWrite) return;  
      try 
      {   
       ms.Write(data, offset, getCountForWrite(offset)); 
       lock (this) 
       { 
        nrReceivedBytes = nrReceivedBytes + getCountForWrite(offset); 
        nrBytesToReceive = screenShotSize - nrReceivedBytes; 
       } 

       if (isScreenShotCompleted() && listener != null) 
       { 
        listener.onReceiveScreenShotComplete(this); 
       } 
      } 
      catch (Exception e) 
      { 
       MessageBox.Show("Error while receiving screenshot" + "\n" + e.GetType() + "\n" + e.StackTrace); 
      } 
     } 




// the code that handles the receiving of a screenshot 
public void onReceiveScreenShotComplete(ScreenShot scr) 
     { 

      this.screenshot = null; 

      if (screen != null && screen.Visible) 
      { 
       screen.updateScreen(scr); 
      }   
     } 


// and the form 
    public partial class Screen : Form 
    { 
     public string screenUniqueIdentifier; 

     public Screen() 
     { 
      InitializeComponent();   
     } 

     public void updateScreen(ScreenShot screenshot) 
     { 
      Image image = Image.FromStream(screenshot.getMemoryStream()); 
      this.Show(); 
      textBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; 
      textBox1.Image = image;   
     } 

可有人請點我我在哪裏做錯了什麼?

回答

1

MSDN:「您必須保持該流在圖像的整個生命週期內都處於打開狀態。」

您可能有一個競賽條件,屏幕截圖中的MemoryStream將在Image物品處置之前處置。這可能會導致異常。我不知道處置Image是否會處理底層流,但如果是這樣,那是另一個可能的問題。

+0

在調用「this.Show()」的行處updateScreen(ScreenShot screenshot)函數中似乎會拋出異常。我正在使用異步套接字 – 2011-03-22 23:11:19

+0

@klaus johan我不熟悉Windows Forms API的內部工作原理。但是,如果Form.Show()實質上導致了圖像的「延遲加載」,這並不會讓我感到驚訝。當然,前面的語句創建了Image,但是對於異步進程,仍然可能存在競爭條件。您必須至少能夠確保該流不會丟棄,並且在整個映像未被丟棄的時間範圍內。 – Andrew 2011-03-23 01:59:09

0

重寫窗體的OnClosing方法並將偵聽器對象(由appendToMemoryStream使用)設置爲null。

最可能發生的情況是,當表單關閉時,您仍在傳輸屏幕。

使用BackgroundWorker然後取消它可能會更好。

相關問題