2012-04-25 5 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 나는 각 소켓과 관련된 threa에서 삭제 메소드 (Disconnection)를 실행 중입니다.

도움 말?

+1

하나의 응용 프로그램에서 여러 스레드 또는 하나의 기본 응용 프로그램과 연결된 여러 응용 프로그램에 대해 이야기합니까? – HW90

+0

배열 대신 배열 을 사용할 수 없습니까? 그럼 당신은 배열의 카운터를 가질 필요가 없습니다. – Reniuz

+0

하나의 응용 프로그램, 여러 스레드 –

답변

1

이 전체 방법을 사용하면 또한 고객의 배열의 변화 때문에 직렬화 할 필요가! 수동으로 카운터를 추적해야 할뿐만 아니라 배열에서 삭제하는 것은 O (n) 작업입니다.

+0

나는 이것이 도움이되었다고 생각하고 스레드를 죽이기 전에 (아니오 -) 아니오를 지정했다. 그래서 분명히 내가 전에 감소하려고했던 스레드를 멈추고 있었다. 실제로 해냈어. 많이 감사합니다! –

+0

오, 나는 더 효율적인 것을하려고 노력할 것입니다. 그것은 내가 처음 마음에 두었던 것입니다. 더 효율적으로하는 방법에 대한 제안은 있습니까? –

+0

@ALex Popa : id 대신 User로 매핑하는 대신, 'Dictionary ' 데이터 구조를 사용할 수 있습니다. 해시 테이블에서 검색 및 삭제는 상수 (상환) 시간입니다. – 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>을 사용하고 직접 카운터를 관리하지 마십시오.

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 

} 

그리고 당신은보다 효율적으로 뭔가 배열을 변경할 수 있는지 확인하십시오 : 제 생각에는

관련 문제