-2

When attempting to close a form, I'm getting a System.ObjectDisposedException on a thread. I tried the suggestions from this similar question: Unexpected "Cannot access a disposed object" in clean up method, but could not prevent the exception from being raised.

MainForm.cs

static ConcurrentDictionary<string, JoystickProcess> clientToDevice;
private Thread listenThread;

public MainForm()
{
    InitializeComponent();

    Network network = new Network(this);
    clientToDevice = new ConcurrentDictionary<string, JoystickProcess>();

    listenThread = new Thread(network.receive);

    // Start threads in background
    listenThread.IsBackground = true;
    listenThread.Start();
}

public JoystickProcess getClient(string client)
{
    if (clientList.InvokeRequired)
    {
        // Causes System.ObjectDisposedException
        return (JoystickProcess) Invoke(new Func<JoystickProcess>(() => getClient(client)));
    }
    else
    {
        JoystickProcess process;
        if (clientToDevice.TryGetValue(client, out process))
            return process;
        return null;
    }
}

Network.cs

private MainForm main;
private List<string> ipList = new List<string>();

public Network(MainForm main)
{
    this.main = main;
}

public void receive() 
{
    int port = 1608;
    UdpClient client = new UdpClient(port);
    IPEndPoint end = new IPEndPoint(IPAddress.Any, port);

    String addr;
    byte[] recv;
    JoystickProcess process;

    while (true)
    {
        // Wait for data to be received
        recv = client.Receive(ref end);

        addr = end.Address.ToString();

        if (ipList.Contains(addr))
        {
            // Causes System.ObjectDisposedException
            process = main.getClient(addr);

            if (process != null && process.getDevice() != -1)
            {
                Task.Run(() => process.updateDevice(recv));
            }
        }
        else
        {
            ipList.Add(addr);
            main.addClient(addr);
        }
    }
}   
Community
  • 1
  • 1
tripleblep
  • 530
  • 7
  • 17
  • 2
    Saying you're getting an exception and then dumping a bunch of code without providing a stack trace or any indication of where the exception is actually occurring makes it difficult to diagnose the problem. – Craig W. Mar 30 '15 at 16:18
  • Where the problem occurs is in fact indicated in the code. – mmg666 Mar 30 '15 at 16:21
  • @Raggeth, I would suggest debugging the code and inspecting all variables and expected values.. you probably are trying to dispose of an object that's already `Null` – MethodMan Mar 30 '15 at 16:23
  • Could you clarify where 'main' is declared and instantiated. It doesn't appear anywhere else in your example code and it is the most likely candidate for causing that error. – Ulric Mar 30 '15 at 16:25
  • @Ulric Sorry, see updated post. – tripleblep Mar 30 '15 at 16:30
  • I have deleted my answer, your object is probably already explicitly disposed. It might be because you are creating more than one instance of it, and your immortal Network class might be referring to an instance that has been disposed. – mmg666 Mar 30 '15 at 16:44

1 Answers1

1

I ended up using a boolean to check if the form is closing. If so, null is returned, which is then checked in the thread itself. My apologies for not making my post as detailed as it should have been.

public JoystickProcess getClient(string client)
{
    if (clientList.InvokeRequired)
    {
        if(shutdown)
            return null;
        return (JoystickProcess) Invoke(new Func<JoystickProcess>(() => getClient(client)));
    }
    else
    {
        JoystickProcess process;
        if (clientToDevice.TryGetValue(client, out process))
            return process;
        return null;
    }
}
tripleblep
  • 530
  • 7
  • 17