2012-04-25 25 views
0

ソケット接続が終了したときに配列内の削除を実行しています。ちょっとしたチャットプログラムで作業しています。ユーザオブジェクトの配列から要素を削除しています。メインスレッドの変数を変更するC#

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 window.but私は各ソケットに関連付けられている3つの方法で削除メソッド(Disconnection)を実行しています。

ヘルプ?

+1

1つのアプリケーションで複数のスレッド、または1つのメインアプリケーションに接続する複数のアプリケーションについて説明しますか? – HW90

+0

配列の代わりにリストを使用できませんか?あなたは配列のカウンターを持つ必要はありません。 – Reniuz

+0

1つのアプリケーション、複数のスレッド –

答えて

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)操作です。

+0

私はこれを助けたと思いますし、私はスレッドを停止していました。実際にそれをした。たくさんのことをありがとう! –

+0

ああ、私はもっと効率的なことをやろうとします。それは私が最初に思いついたものでした。それをより効率的にする方法の提案はありますか? –

+0

@ALex Popa:代わりに 'Dictionary 'データ構造を使って、idをUserにマッピングすることができます。ハッシュテーブルからの検索と削除は、一定(償却された)時間です。 – Tudor

2

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

0

これはあなたの質問に直接答えるものではありません。なぜなら、私はちょっとしたポイントを持っているからです。

まず、自動プロパティを使用してみませんか?代わりに:

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

あなたはあなたの特性のすべてのためにこれを行うことができます

public Thread CLThread { get; set; } 

を試してみてください。

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

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

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