4

.NET で名前付きパイプを使用する必要があり、Windows フォーム GUI の背後で実行される非常に単純なサーバーを構築しています。「サーバー」クラス (以下) に ServiceHost を実装し、「クライアント」クラスを使用して通信することができました。私が抱えている問題は、フォームが閉じられたときにスレッドを破棄するだけでなく、スレッドで実行されている 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 を使用することはこれに対する適切なアプローチですか? また、スレッドの処理が終了したときに Dispose() を呼び出すにはどうすればよいですか?

4

1 に答える 1

9

あなたはこれを必要以上に難しくしています。

  1. 開始するスレッドを作成しないでくださいServiceHostServiceHostサービス呼び出しのために内部で独自のスレッドを管理します。を開始するためだけに新しいスレッドを作成する利点はありませんServiceHost。また、クライアントの呼び出しは、が初期化されて実行Connect()されるまで成功しません。したがって、 と の間にServiceHostは同期が必要です。新しいスレッドはあなたを救っていません。server.Start()client.Connect()

  2. よほどの理由がない限り、C# でファイナライザーを実行しないでください。~Server()悪い考えです。

したがって、Serverクラスを完全に削除します。ラッパーは何も購入しません (投稿されたコードに表示されていない構成管理を行っている場合を除きます)。

でサービス ホストを作成し、をMyForm()呼び出します。終わり。host.Close()MyForm_FormClosed()

于 2013-10-26T21:35:09.457 に答える