【问题标题】:object disposed exception对象处理异常
【发布时间】:2009-05-16 19:51:42
【问题描述】:

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

  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 已被释放。这怎么可能?有什么需要做的吗?

【问题讨论】:

  • 请编辑您的问题并输入一些适当的标签,并不是每个人都熟悉您之前提到的问题。
  • @micro:它在 c# 中。 @duckflip:我的整个程序非常大,可以在这里展示。能不能具体告诉我你没看懂的地方,以便我提供必要的相关代码。

标签: c# objectdisposedexception


【解决方案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 接收器,再次假设我的假设是正确的。

【讨论】:

    【解决方案2】:

    对此块的评论:

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

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

    【讨论】:

    • 不正确 - 调用是同步的。运行此代码的线程将等到委托完成后再继续。如果这段代码在 UI 线程上运行,listBox 确实会为 null(因此 InvokeRequired 为 false)
    猜你喜欢
    • 1970-01-01
    • 2011-05-23
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多