2013-10-25 9 views
3

.NET에서 명명 된 파이프를 사용해야하는 매우 간단한 서버를 구축 중이며 Windows Forms GUI에서 실행됩니다. 나는 '서버'클래스 (아래)에서 ServiceHost를 구현하고 '클라이언트'클래스를 사용하여 통신 할 수 있었다. 내가 겪고있는 문제는 스레드에서 실행중인 ServiceHost를 닫는 올바른 방법을 알아내는 것뿐 아니라 폼이 닫힐 때 스레드를 삭제하는 것입니다. 나는 쓰레드와 명명 된 파이프에 익숙하지 않아서 좋다.


이 내 서버/클라이언트 시작하는 형태이다 :C#에서 ServiceHost 스레드를 닫거나 처리하는 올바른 방법은 무엇입니까?

public partial class MyForm : Form 
{ 
    Thread server; 
    Client client; 

    public MyForm() 
    { 
     InitializeComponent(); 

     server = new Thread(() => new Server()); 
     server.Start(); 

     client = new Client(); 
     client.Connect(); 
    } 
} 

private void MyForm_FormClosed(object sender, FormClosedEventArgs e) 
{ 
    // Close server thread and disconnect client. 
    client.Disconnect(); 

    // Properly close server connection and dispose of thread(?) 
} 



을 그리고 여기에 서버 클래스입니다 :

class Server : IDisposable 
{ 
    public ServiceHost host; 
    private bool disposed = false; 

    public Server() 
    { 
     host = new ServiceHost(
      typeof(Services), 
       new Uri[]{ 
       new Uri("net.pipe://localhost") 
      }); 

     host.AddServiceEndpoint(typeof(IServices), new NetNamedPipeBinding(), "GetData"); 
     host.AddServiceEndpoint(typeof(IServices), new NetNamedPipeBinding(), "SubmitData"); 
     host.Open(); 

     Console.WriteLine("Server is available."); 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if(!this.disposed) 
     { 
      if(disposing) 
      { 
       host.Close(); 
      } 

      disposed = true; 
     } 
    } 

    ~Server() 
    { 
     Dispose(false); 
    } 
} 



이는 IDisposable a를 사용 이것에 대한 좋은 접근 방법, 그리고 어떻게하면 C alling 내 스레드가 끝나면 Dispose()?

답변

8

당신은 이것을 필요 이상으로 어렵게 만들고 있습니다.

  1. ServiceHost을 시작하는 스레드를 만들지 마십시오. ServiceHost은 서비스 호출을 위해 자체 스레드를 내부적으로 관리합니다. ServiceHost을 시작하기위한 새로운 스레드를 만드는 데는 이점이 없습니다. 또한 클라이언트 Connect() 호출은 ServiceHost이 초기화되어 실행될 때까지 성공하지 못합니다. 따라서 server.Start()과 사이의 동기화가 필요합니다. 새 스레드가 저장하지 않습니다.

  2. 매우 좋은 이유가없는 한 Finalizers는 C#으로하지 마십시오. ~Server() 나쁜 아이디어입니다.

따라서 Server 클래스를 완전히 제거하십시오. 래퍼는 게시 된 코드에 표시되지 않는 구성 관리를 수행하지 않는 한 아무 것도 사지 않습니다.

MyForm()에 서비스 호스트를 만들고 host.Close()MyForm_FormClosed()으로 호출하십시오. 끝난.

+0

'서버'클래스 제거는 의미가 있습니다. 내 'Client' 클래스에서'ServiceHost'를 호출하려고 할 때 응용 프로그램이 잠겨 있었기 때문에 원래 스레드를 만들었습니다. 스레드 사용에 대한 이해가 부족한 것 같습니다. 감사합니다 @ ErnieL! –