简体   繁体   English

在C#中关闭/处置ServiceHost线程的正确方法?

[英]Proper way to close/dispose of a ServiceHost Thread in C#?

I am building a very simple server that has to use named pipes in .NET, and will be ran behind a Windows Forms GUI. 我正在构建一个非常简单的服务器,它必须在.NET中使用命名管道,并将在Windows窗体GUI之后运行。 I have been able to implement a ServiceHost in a 'Server' class (below) and communicate with it using a 'Client' class. 我已经能够在'Server'类(下面)中实现ServiceHost,并使用'Client'类与它进行通信。 The problem I am having is figuring out the proper way to close the ServiceHost that is running on a thread, as well as disposing of the thread when the form is closed. 我遇到的问题是找出关闭在线程上运行的ServiceHost的正确方法,以及在窗体关闭时处理线程。 I am new to threads and named pipes, so be nice! 我是线程和命名管道的新手,所以要好!


This is the form which starts my server/client: 这是启动我的服务器/客户端的表单:

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(?)
}



And here is the Server class: 这是Server类:

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);
    }
}




Is using IDisposable a good approach to this, and how do I go about calling Dispose() when I'm finished with my thread? 使用IDisposable是一个很好的方法,当我完成我的线程时如何调用Dispose()?

You are making this harder than it needs to be. 你正在变得比它需要的更难。

  1. Don't create a thread to start ServiceHost . 不要创建一个线程来启动ServiceHost ServiceHost will manage its own threads internally for the service calls. ServiceHost将在内部管理自己的线程以进行服务调用。 There's no advantage to creating a new thread just to start the ServiceHost . 创建一个新线程只是为了启动ServiceHost没有任何好处。 Also your client Connect() call won't succeed until the ServiceHost is initialized and running. ServiceHost初始化并运行之前,您的客户端Connect()调用也不会成功。 So there's required synchronization between server.Start() and client.Connect() . 因此,有需要的同步server.Start()client.Connect() The new thread isn't saving you anything. 新线程没有保存任何东西。

  2. Do not do Finalizers in C# unless you have a very good reason. 除非你有充分的理由,否则不要在C#中使用Finalizer。 ~Server() is a bad idea. ~Server()是个坏主意。

So get rid of the Server class entirely. 所以完全摆脱Server类。 The wrapper isn't buying you anything (unless you are doing configuration management that isn't shown in the posted code). 包装器不会为您购买任何东西(除非您正在进行未在发布的代码中显示的配置管理)。

Create the service host in MyForm() and call host.Close() in MyForm_FormClosed() . 创建服务主机MyForm()并调用host.Close()MyForm_FormClosed() Done. 完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM