客户端服务器应用程序中的ObjectDisposedException

时间:2016-06-18 17:23:19

标签: c# tcp tcpclient objectdisposedexception binary-serialization

我已经在C#课程中收到了一项任务,即使用TcpClient / TcpServer类,使用序列化&amp ;;在WinForms中构建多客户端聊天。通过BinaryFormatter进行反序列化。

当我在客户端使用Disconnect方法时,我会立即在incomingData = binFormat.Deserialize(stream);行上收到此错误。

ObjectDisposedException - Cannot access a disposed object

客户端代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using CommonResources;
using System.Windows.Forms;
using System.IO;

namespace shekerclient
{
    [Serializable]

    public class ClientConnection
    {
        GuestInfo ClientInformation;
        GuestMenager ClientStats;
        Thread clientListenThread;
        public IPEndPoint ServeripAdress;
        public TcpClient tcpUser;
        private IncomingMessageManager Menage;
        private bool IsConnected;
        BinaryFormatter binFormat = new BinaryFormatter();
        public int onlineUsers;
        NetworkStream stream;

        public bool ConnectionStatus
        {

            get { return IsConnected; }

        }

        public ClientConnection(string ip, int port, IncomingMessageManager Mngr,
               GuestInfo clientInformation, GuestMenager ClientStats)
        {

            ServeripAdress = new IPEndPoint(IPAddress.Parse(ip), port);
            this.ClientStats = ClientStats;
            this.ClientInformation = clientInformation;
            Menage = Mngr;
            Connect();

            if (tcpUser.Client.Connected)
            {
                var stream = tcpUser.GetStream();
                clientListenThread = new Thread(new ParameterizedThreadStart(Recieve));
                clientListenThread.IsBackground = true;
                clientListenThread.Start(null);
                Thread.Sleep(2000);
                binFormat.Serialize(stream, ClientInformation);
            }

        }
        public void Connect()
        {
            try
            {
                tcpUser = new TcpClient();
                tcpUser.Connect(ServeripAdress);
                IsConnected = true;
            }
            catch (Exception Error)
            {
                MessageBox.Show(Error.Message);
            }
        }

        public void Send(object Msg)
        {
            Msg = (ChatMessage)Msg;

            var SendStream = tcpUser.GetStream();

            binFormat.Serialize(SendStream, Msg);
        }

        public void Recieve(object Info)
        {
            this.stream = tcpUser.GetStream();

            while (true)
            {
                if (IsConnected)
                {
                    {
                        object incomingData = null;

                        try
                        {
                            incomingData = binFormat.Deserialize(stream);
                        }
                        catch (IOException Error)
                        {
                            MessageBox.Show(Error.Message);
                        }


                        if (incomingData != null && incomingData.GetType()==typeof(GuestInfo))

                        {
                            var ClientInfo = incomingData as GuestInfo;
                            ClientStats.AddGuest(ClientInfo);
                        }
                        else if (incomingData != null && incomingData.GetType()==typeof(ChatMessage))
                        {

                            var Msg = incomingData as ChatMessage;
                            Menage.AddMessage(Msg);

                        }

                    }
                }
            }


        }


        public void Disconnect()
        {

            IsConnected = false;
            tcpUser.GetStream().Flush();
            tcpUser.Client.Disconnect(false);
            tcpUser.Close();
            tcpUser = null;
        }


    }
}

1 个答案:

答案 0 :(得分:0)

您应该JOIN()线程而不是在下面说,因为当您的线程尝试访问binFormat实例时,您的主线程已经被清除,因此实例字段已被处理掉。因此,您收到了上述例外情况。

clientListenThread.Start();
clientListenThread.Join();

您也可以考虑更改方法签名以接收一个BinaryFormatter实例,如下所示

    public void Recieve(object Info, BinaryFormatter formatter)
    {

(OR)您在方法块内创建一个相同的实例,并使用相同的

    public void Recieve(object Info)
    {
       BinaryFormatter format = new BinaryFormatter();
       incomingData = format.Deserialize(stream);