2016-09-05 5 views
0

은 내가 button1을 가진 폼이 코드왜 서버 tcp를 시작하면 양식이 사라 집니까?

private void button1_Click(object sender, EventArgs e) 
{ 
    ServerTCP s = new ServerTCP(); 
} 

그리고 문제는 내가 button1을 클릭 한 후, 양식이 사라지고 있다는 것이다 클래스 serverTCP

public ServerTCP() 
{ 
    TcpListener listen = new TcpListener(IPAddress.Any, 1200); 
    Console.WriteLine("Waiting"); 
    listen.Start(); 
    while (true) 
    { 
     TcpClient client = listen.AcceptTcpClient(); 
     Console.WriteLine("Client connected"); 
     NetworkStream stream = client.GetStream(); 
     byte[] buffer = new byte[client.ReceiveBufferSize]; 
     int data = stream.Read(buffer, 0, client.ReceiveBufferSize); 
     string message = Encoding.Unicode.GetString(buffer, 0, data); 
     int idgiorno = Int32.Parse(message); 
     Console.WriteLine("idgiorno: " + idgiorno); 
     client.Close(); 
    } 
} 

있습니다. 시작 막대에서 여전히 실행 중임을 볼 수 있지만 아이콘을 클릭하더라도 표시되지 않습니다. 이것은 양식이 초점을 잃는 것과 같습니다.

+0

프로그램의 주 스레드에서 연속 루프가 실행되어 충돌을 일으켜 사용하지 못하는 것처럼 보입니다. – ThePerplexedOne

+0

프로그램은 클라이언트로부터 입력을 기다리는 서버입니다. 하지만 응용 프로그램을 닫으려면 다른 단추가 있어야하기 때문에 양식에 초점이 필요합니다 – Alessandro

+0

그런 다음 주 스레드와 별도의 스레드에서 코드를 실행하십시오. 스레딩에 대한 자세한 내용은 [https://msdn.microsoft.com/en-us/library/aa645740(v=vs.71) .aspx)를 참조하십시오. – ThePerplexedOne

답변

0

여기에서 당신이하려는 것을 볼 수는 있지만,이 비트를 고치더라도 문제가 발생할 수 있습니다.

첫 번째로 먼저 말했듯이, 폼을 잃어버린 이유는 메인 스레드에서 무한 루프를 입력했기 때문입니다. 이를 피하려면 다음을 사용하십시오.

using System.Threading.Tasks 
public ServerTCP() 
{ 
    TcpListener listen = new TcpListener(IPAddress.Any, 1200); 
    Console.WriteLine("Waiting"); 
    listen.Start(); 
    Task myTask = new Task(() => 
    { 
     while (true) 
     { 
      TcpClient client = listen.AcceptTcpClient(); 
      Console.WriteLine("Client connected"); 
      NetworkStream stream = client.GetStream(); 
      byte[] buffer = new byte[client.ReceiveBufferSize]; 
      int data = stream.Read(buffer, 0, client.ReceiveBufferSize); 
      string message = Encoding.Unicode.GetString(buffer, 0, data); 
      int idgiorno = Int32.Parse(message); 
      Console.WriteLine("idgiorno: " + idgiorno); 
      client.Close(); 
     } 
    }); 
    myTask.Start(); 
} 

이것은 자신이 관리 대상을 만들지 않고도 풀에서 여분의 스레드로 작업을 디스패치하는 게으른 방법입니다. 위임을 람다 식이라고 부릅니다.

https://msdn.microsoft.com/en-GB/library/bb397687.aspx

이 문제는이 스레드 어쨌든 콘솔 리소스에 액세스 할 수없는 것입니다, 그래서 당신은 당신의 메시지를 볼 수 없습니다 두려워.

코드에서 모든 것을 "절차 적으로"작성했습니다. 즉, 각 단계에 필요한 전제 조건이 있다고 가정하고 지침 목록을 작성했음을 의미합니다. 예를 들어;

byte[] buffer = new byte[client.ReceiveBufferSize]; 

아직 데이터를받지 못했다면 0으로 버퍼를 초기화하려고 시도하면 세상이 끝납니다.

단계별로이 모든 것을 단계적으로 수행하기보다는이 두 개의 유튜브 비디오를 훌륭한 소개로 시청하십시오. 그들은 완벽하지는 않지만 앞으로 나아갈 수 있도록 도와야합니다.

https://www.youtube.com/watch?v=NanjpGKC2js

https://www.youtube.com/watch?v=uXFso7xSSWk

정말, 응용 프로그램에 접근하는 유일한 강력한 방법은 "이벤트 구동 프로그램"을 통해,하지만 그것은 또 다른 하루 일 수 있습니다.

행운을 빌어 요!

0

음, 기본적으로 다음과 같은 호출은 결코 반환 :

ServerTCP s = new ServerTCP(); 

ServerTcp의 생성자는 무한 루프 포함되어 있으므로 호출은 또한 블록 UI 스레드 반환하지 않습니다뿐만 아닙니다. UI 스레드가 차단되면 WM_ACTIVATE 또는 WM_PAINT와 같은 창 메시지가 처리되지 않으므로 양식을 사용할 수 없게됩니다.

TcpListener을 비동기 적으로 사용해야합니다. This is a good starting point. BeginAcceptTcpClient을 반복적으로 호출하면 서버가 계속 실행되므로 루프도 제거됩니다.

관련 문제