1

好的,伙计们,我的代码中突然出现了这个以前没有出现过的问题。

  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 已处置,因此无法执行。这怎么可能,有什么需要做的吗?

4

2 回答 2

1

我做出以下假设:

  1. 此代码是 Form (System.Windows.Forms.Form) 中的一个方法。
  2. 变量“listBox1”是窗体上的一个 ListBox 控件。
  3. 当表单关闭时,您将收到 ObjectDisposedException。
  4. 您在单独的线程上运行此方法(代码中未显示,但问题暗示)。

我猜想您的代码在表单关闭时阻塞了套接字上的 receiveFrom() 调用。从网络到达的下一条消息会导致 receiveFrom 返回,之后您将收到的消息放入不再存在的列表框中。第一次访问此列表框是创建 StringBuilder 时的代码行“this.listBox1.Text”,这是引发 ObjectDisposeException 的行。listBox 是可能被释放的对象,尽管此时它也可能是 Form,这取决于消息进入的速度。

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

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

于 2009-10-29T11:53:07.283 回答
-1

对此块的评论:

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

在您执行 .AppendLine 时,StringBuilder(列表框)可能为空。这是因为您在与使用它的位置不同的线程中创建列表框。此外,仅当此代码在非 UI 线程上运行时(这就是 listBox1.InvokeRequired)正在检查的,才会创建一个新的 StringBuilder 对象。

于 2009-05-21T12:53:03.623 回答