对象处置例外

时间:2009-05-16 19:51:43

标签: c# objectdisposedexception

好的,我的代码中存在这个突然出现的问题,之前没有出现过..

  public void StartUdpListener(Object state)
    {


       /* sock1 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        sock1.Bind(receiveEndPoint);

        EndPoint ep = (EndPoint)receiveEndPoint;*/



       recv = sock1.ReceiveFrom(receivedNotification, ref ep);

       notificationReceived = Encoding.ASCII.GetString(receivedNotification, 0, recv);

       //sock1.Close();

       if (listBox1.InvokeRequired)
       {
           this.Invoke((MethodInvoker)delegate { listBox = new StringBuilder(this.listBox1.Text); });
       }
       listBox.AppendLine(notificationReceived);


       if (listBox1.InvokeRequired)
       {
           pos = listBox1.FindString(notificationReceived);
           if (pos >= 0)
           {
           }
           else
           {
               this.Invoke((MethodInvoker)delegate { this.listBox1.Items.Add(listBox.ToString()); });
           }
       }

    }

我收到一条ObjectDisposedException,表示该行:

   this.Invoke((MethodInvoker)delegate { listBox = new StringBuilder(this.listBox1.Text); });
由于listBox1被处理,因此无法执行

。怎么可能,还有什么需要做的吗?

2 个答案:

答案 0 :(得分:1)

我做出以下假设:

  1. 此代码是Form(System.Windows.Forms.Form)中的方法。
  2. 变量'listBox1'是表单上的ListBox控件。
  3. 表单关闭时,您收到ObjectDisposedException。
  4. 您正在一个单独的线程上运行此方法(代码中未显示,但问题暗示)。
  5. 我猜想在窗体关闭时,代码在套接字上的receiveFrom()调用时会阻塞。从网络到达的下一条消息会导致receiveFrom返回,之后您将收到的消息放入不再存在的列表框中。在创建StringBuilder时,第一次访问此列表框是代码行“this.listBox1.Text”,这是引发ObjectDisposeException的行。 listBox是可能被处置的对象,虽然它也可能是此时的表单,取决于消息的进入速度。

    似乎有很多事需要做,但我不确定什么是正确的建议。我首先验证上面的假设1-4,然后考虑重构你的应用程序,使它不使用多个线程。我提出这个建议是因为我必须假设这不是你的应用程序可能遇到的唯一“线程”问题。我肯定在这个假设中可能不正确,在这种情况下你可以忽略答案。

    如果我将问题的“需要做的事情”限制在更有限的范围内,那么我建议在允许窗口关闭之前正确关闭UDP接收器,再次假设我的假设是正确的。

答案 1 :(得分:-1)

对此块的评论:

if (listBox1.InvokeRequired)
{
    this.Invoke((MethodInvoker)delegate { listBox = new
        StringBuilder(this.listBox1.Text); });
}
listBox.AppendLine(notificationReceived);

StringBuilder(listbox)在你执行的时候可能为null .AppendLine。这是因为您在与使用它的位置不同的线程中创建列表框。如果此代码在非UI线程(即listBox1.InvokeRequired)检查时运行,则只会创建一个新的StringBuilder对象。