"Can not access a disposed object" exception

  • Thread starter Thread starter Ahmad Jalil Qarshi
  • Start date Start date
A

Ahmad Jalil Qarshi

Hi,

I have developed a Windows based C# application. Form contains a Label
control. Now I have created a child thread which
reads some data from a socket and on SocketException it sets the Text
property of Label control. I have made this Label
control thread safe. The thread function is as follows:

private void ReceiveThreadFunc()
{
int nRead
try
{
nRead = ClientSock.Receive(btRec, 0, btRec.Length, SocketFlags.None);
while(nRead>0)
{
//Do some processing
nRead = ClientSock.Receive(btRec, 0, btRec.Length, SocketFlags.None);
}
} catch(SocketException se)
{
//Display Error message
}
finally
{
SetLabelText("Thread exited");
}
}

In the Form class I have declared a delegate to make the Label control
Thread safe. Which is given hereunder:

delegate void SetStatusTextCB(string text);

public void SetStatusText(string text)
{
if (this.labelStatus.InvokeRequired)
{
SetStatusTextCB d = new SetStatusTextCB(SetStatusText);
this.Invoke(d, new object[] { text });
}
else
{
this.labelStatus.Text = text;
}
}

I have a Close Button on the Form. In the Click event of Close Button I am
doing some processing as well as I close the
above mentioned thread and socket as follows:

if(m_ReceiveThread != null && m_ReceiveThread.isAlive)
{
m_ReceiveThread.Abort();
}
if(ClientSock != null && ClientSock.Connected)
ClientSock.Close();

this.Close(); //Close main application


The problem is that when in Debug mode I click the close button, I receive
an exception at following line in above mentioned
SetStatusText function:

this.Invoke(d, new object[] { text });

The exception is "Can not access a disposed object".

Any solution to overcome this problem?

Thanks in anticipation.

Regards,

Ahmad Jalil Qarshi
 
[...]
this.Invoke(d, new object[] { text });

The exception is "Can not access a disposed object".

Any solution to overcome this problem?

Yes. Don't try to access a disposed object.

You are calling Invoke() on a control that's already been disposed,
presuambly when you closed the form. You should fix your code so that it
doesn't try to call Invoke() after the form's been closed. You can do
this in a variety of ways, all being variations on the themes of either
not closing the form until you've completely shut down the network
processing, or not trying to update the form if it's been closed.

Also, don't call Thread.Abort(). That's not a good way to clean threads
up. There are lots of other options, all involving allowing the thread to
detect when it's done whatever it's doing and exiting by itself.

Pete
 
Back
Top