2011-03-22 52 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然后取消它可能会更好。

相关问题