2011-09-19 5 views
3

나는 별도의 스레드 (작업)에서이 코드가 응용 프로그램이 종료 될 때까지 응용 프로그램이 시작 및 종료 안 때 먼저 실행 :이 경우TcpListener.Stop()을 호출해야합니까?

TcpListener tcpListener = new TcpListener(IPAddress.Any, port); 

tcpListener.Start(); 

while (true) 
{ 
    TcpClient client = tcpListener.AcceptTcpClient(); 

    Task.Factory.StartNew(HandleClientCommunication, client); 
} 

그것은 tcpListener.Stop()를 호출 할 필요가? 이 스레드는 응용 프로그램의 전체 기간 동안 실행되며 호출해야한다면 어디에서 그렇게할까요? 리스너는이 스레드에 대해 로컬입니다. while (true) 루프 대신에 while (appRunning) 루프가 있고 FormClosing 이벤트에서 appRunning을 false로 설정해야합니까? 그런 다음 while 루프를 호출 한 후 tcpListener.Stop()으로 전화 할 수 있습니다.

TcpListener.Stop()하지만 응용 프로그램이 이미 종료되어 있고 Tasks를 사용하고 있으므로이 프로세스도 종료되기 때문에 전화를 걸어도됩니까? 그런

+0

올바른 방법으로 TcpListener를 중지 할 수 있습니다. (http://stackoverflow.com/questions/365370/properway-to-stop-tcplistener) – Kiril

+0

개발자가 스레드를 중지해야하는 몇 가지 이유가 있습니다 명백하게. 닷넷 애플 리케이션 닫기 - 그들은 다른 devleopers 그것을 볼 때, 그것은 '깨끗한'또는 자신의 작업 스레드가 직접/양식/구성 요소/양식이 닫히면 애플 리케이션을 잃는 동안 할당이 취소 된 데이터에 직접 쓰기 때문에, (그래서 AV/segfault 등 생성). 리스너 스레드 자체는 명시 적 중지가 필요하지 않으므로 OS가 메인 스레드가 닫히고 ExitProcess()를 호출 할 때 수행하도록하십시오. –

+0

@ 짐 :이 문제를 해결하기 위해이 상황에서 취소 토큰을 구현하는 방법에 대한 몇 가지 예제 코드를 제공하고 싶다면 그 대답으로 기꺼이 받아 들일 것입니다. –

답변

2

시도 뭔가 : - 클라이언트 (수면에서 밀리 초)을 채택 사이에 약간의 지연이있을 것, 나쁜 이잖아 TcpListener.Pending()

public class Listener 
{ 
    private readonly TcpListener m_Listener = new TcpListener(IPAddress.Any, IPEndPoint.MinPort); 
    private CancellationTokenSource m_Cts; 
    private Thread m_Thread; 
    private readonly object m_SyncObject = new object(); 

    public void Start() 
    { 
     lock (m_SyncObject){ 
      if (m_Thread == null || !m_Thread.IsAlive){ 
       m_Cts = new CancellationTokenSource(); 
       m_Thread = new Thread(() => Listen(m_Cts.Token)) 
        { 
         IsBackground = true 
        }; 
       m_Thread.Start(); 
      } 
     } 
    } 

    public void Stop() 
    { 
     lock (m_SyncObject){ 
      m_Cts.Cancel(); 
      m_Listener.Stop(); 
     } 
    } 

    private void Listen(CancellationToken token) 
    { 
     m_Listener.Start(); 
     while (!token.IsCancellationRequested) 
     { 
      try{ 
       var socket = m_Listener.AcceptSocket(); 
       //do something with socket 
      } 
      catch (SocketException){      
      } 
     } 
    } 
} 

접근은 그런 Thread.Sleep(miliseconds) 또는 무언가를 사용해야하기 때문에 너무 좋지 않다.

+0

당신이 만든 아름다운 수업에 감사드립니다. 제가하고있는 프로젝트에 매우 유용합니다. –

+0

이 솔루션의 문제점은 AcceptSocket 메서드가 차단되고 있다는 것입니다. 들어오는 연결을 기다리는 동안 청취 스레드를 정상적으로 중지 할 수있는 방법이 없습니다. –

관련 문제