"Can not access a disposed object" exception

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
 
P

Peter Duniho

[...]
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top