views:

1003

answers:

2

Ok guys there is this sudden problem in my code which didn't appear before..

  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()); });
           }
       }

    }

I am getting an ObjectDisposedException saying that the line:

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

cannot be executed since listBox1 is disposed.How is that possible and is there anything that needs to be done?

A: 

A comment on this block:

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

The StringBuilder (listbox) may be null at the point you do .AppendLine. This is because you are creating the listbox in a different thread to where you using it. Also a new StringBuilder object only gets created if this code is run on a non UI thread (thats what listBox1.InvokeRequired) is checking.

Kevin
Incorrect - Invoke is synchronous. The thread that is running this code will wait until the delegate has completed before carrying on. It is true that listBox will be null if this code is running on the UI thread (so InvokeRequired is false)
thecoop
+1  A: 

I am making the following assumptions:

  1. This code is a method in a Form (System.Windows.Forms.Form).
  2. The variable 'listBox1' is a ListBox control on the form.
  3. You are receiving the ObjectDisposedException when the form is closed.
  4. You are running this method on a separate thread (not shown in the code, but implied by the question).

I would guess that your code is blocking on the receiveFrom() call on the socket when the form is closed. The next message that arrives from the network causes receiveFrom to return, after which you put the message received into a listbox that no longer exists. The first time you access this listbox is code line "this.listBox1.Text" when creating the StringBuilder, which is the line that raises the ObjectDisposeException. The listBox is the object that is likely disposed, although it could also be the Form at this point, depening on how fast messages are coming in.

There appears to be plenty that needs to be done, but I am not sure what is proper advice. I would first validate my assumptions 1-4 above, then look into refactoring your application such that it does NOT use multiple threads. I make this suggestion because I must assume this is not the only "threading" issue your application may have. I certaintly may be incorrect in that assumption, in which case you can ignore the answer.

If I restrict the "what needs to be done" part of your question to a more limited scope, then I would advise to properly shutdown your UDP receiver before allowing the window to close, again assuming my assumptions are correct.

Bill