2013-10-25 5 views
3

Я строю очень простой сервер, который должен использовать именованные каналы в .NET, и будет работать за графическим интерфейсом Windows Forms. Я смог реализовать ServiceHost в классе «Сервер» (см. Ниже) и общаться с ним с использованием класса «Клиент». Проблема, с которой я столкнулась, заключается в том, чтобы правильно установить ServiceHost, который работает на потоке, а также избавиться от потока, когда форма закрыта. Я новичок в потоках и именованных каналах, так что будь красивой!


Это форма, которая начинается мой клиент/сервер:Правильный способ закрыть/удалить поток ServiceHost на C#?

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() и client.Connect(). Новая нить ничего не спасает.

  2. Не делайте финализаторы в C#, если у вас нет веской причины. ~Server() - плохая идея.

Так что полностью избавитесь от класса Server. Обертка ничего не покупает (если вы не выполняете управление конфигурацией, которая не показана в опубликованном коде).

Создайте хозяин сервиса в MyForm() и позвоните host.Close() в MyForm_FormClosed(). Готово.

+0

Устранение класса 'Server' имеет смысл. Я изначально создал поток, потому что мое приложение блокировалось, когда я пытался вызвать «ServiceHost» из моего класса «Клиент». Я думаю, что мне не хватает понимания использования потоков. Спасибо @ErnieL! –