尝试关闭表单时出现ObjectDisposedException

时间:2015-03-30 16:13:52

标签: c#

尝试关闭表单时,我在某个帖子上获得System.ObjectDisposedException。我尝试了这个类似问题的建议:Unexpected "Cannot access a disposed object" in clean up method,但无法防止引发异常。

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

1 个答案:

答案 0 :(得分:1)

我最终使用布尔值来检查表单是否正在关闭。如果是,则返回null,然后在线程本身中检查。我很抱歉没有尽可能详细地发布我的帖子。

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