0

ソケット接続が終了したときに、配列で削除を行っています。ちょっとしたチャット プログラムに取り組んでいます。ユーザー オブジェクトの配列から要素を削除しています。

public class User
{

    private Thread clthread;
    private string name;
    private Socket sock;

    public User(string _name, Thread _thread, Socket _sock)
    {
        sock = socket();
        clthread = _thread;
        name = _name;
        sock = _sock;
    }

    private Socket socket()
    {
        return new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    }//initiaza socket nou

    public Thread CLThread
    {
        get { return clthread; }
        set { clthread = value; }
    }
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    public Socket Sock
    {
        get { return sock; }
        set { sock = value; }
    }

}

配列は次のように宣言されます。

   User[] connected = new User[1024];  

そして、これが私が削除している方法です

            private void Disconnection(int id)
    {
        User client = connected[id];
        for (int i = id; i < no - 1; i++)
        {
            connected[i] = connected[i + 1];
        }
        client.Sock.Close();
        client.CLThread.Abort();


        no--;
        MessageBox.Show(no.ToString());
        //ui clean

    }

問題は、ユーザー配列のカウンターがメインのwpfウィンドウで宣言されていることですが、各ソケットに関連付けられたスレッドで削除メソッド(切断)を実行しています。

ヘルプ?

4

3 に答える 3

2

複数のスレッドからデクリメントしているため、ユーザー配列のカウンターの周りにロックを使用します。

于 2012-04-25T13:11:03.280 に答える
1

私の意見では、クライアントの配列も変更しているため、このメソッド全体をシリアル化する必要があります。

object locker = new object(); // globally visible lock

...

private void Disconnection(int id)
{        
    lock(locker)
    {
        User client = connected[id];
        for (int i = id; i < no - 1; i++)
        {
            connected[i] = connected[i + 1];
        }
        client.Sock.Close();
        client.CLThread.Abort();

        no--;      
        MessageBox.Show(no.ToString());
    }
    //ui clean

}

そして、配列をより効率的なものに変更できるかどうかを確認してください! カウンターを手動で追跡する必要があるだけでなく、配列からの削除は O(n) 操作です。

于 2012-04-25T13:58:32.050 に答える
0

これはあなたの質問に直接答えているわけではありません。私が提起すべきいくつかのポイントがあるからです。

まず、自動プロパティを使用してみませんか?それ以外の:

public Thread CLThread
{
    get { return clthread; }
    set { clthread = value; }
}

試す

public Thread CLThread { get; set; }

これは、すべてのプロパティに対して実行できます。

また、切断の詳細を外部に公開しています。クラスには、ソケットのクローズとスレッドの中止を処理するパブリックClose()メソッドが必要です。User

とはいえ、スレッドを中止することは悪です。イベントが通知されたときにスレッドを正常に返すようなアプローチを使用してから、スレッドのJoin()メソッドを呼び出してClose()スレッドが終了するのを待つ必要があります。

私はReniuzに同意します-List<User>代わりに使用し、自分でカウンターを管理することは避けてください。

于 2012-04-25T13:48:51.950 に答える