C# 当用户调用时关闭线程

C# 当用户调用时关闭线程,c#,multithreading,C#,Multithreading,我有一个简单的WinForms应用程序,用作多个TelNet客户端的服务器。当这些客户端中的每一个连接时,就会创建一个新线程。这一切都很好。然而,我还没有找到合适的方法在需要时关闭这些线程。 我在网上找到的所有示例都使用Thread.Abort(我知道这是个坏主意)或处理从同一类创建的线程,这不是我需要做的 这是我的课程的简化版本: 主UI类: private void btnStart_Click(object sender, EventArgs e) { _listener = ne

我有一个简单的WinForms应用程序,用作多个TelNet客户端的服务器。当这些客户端中的每一个连接时,就会创建一个新线程。这一切都很好。然而,我还没有找到合适的方法在需要时关闭这些线程。 我在网上找到的所有示例都使用
Thread.Abort
(我知道这是个坏主意)或处理从同一类创建的线程,这不是我需要做的

这是我的课程的简化版本:

主UI类:

private void btnStart_Click(object sender, EventArgs e)
{
    _listener = new TelNetListener(_deviceConnection);
}

private void btnStop_Click(object sender, EventArgs e)
{
    // NEED TO SIGNAL Listener and all Client threads to stop here.
}
public TelNetListener(DeviceConnection deviceConnection)
{
    Thread thread = new Thread(() => TelNetListenerStart(deviceConnection));
    thread.Start();
}

private void TelNetListenerStart(DeviceConnection deviceConnection)
{
    Socket listener;
    listener = new Socket(AddressFamily.InterNetwork, 
        SocketType.Stream, ProtocolType.Tcp);
    listener.Bind(ipEndPoint);
    listener.Listen(100);

    _allDone = new ManualResetEvent(false);

    while (true)
    {
        _allDone.Reset();
        listener.BeginAccept(new AsyncCallback(AcceptCallBack), listener);
        _allDone.WaitOne();
    }
}

private void AcceptCallBack()
{
    telNetClient = new TelNetClient(clientSocket, string.Format("ACTN{0}",
        _clientCounter.ToString("D4")));
}
侦听器类(从主UI类创建的线程):

客户端类(从侦听器类创建的线程):

请记住,有相当数量的代码丢失,所以如果有未声明的变量或类似的东西,请忽略它们。我只是不想输入大量不相关的代码

我看到过使用
ManualResetEvent
的示例,这似乎是我需要做的,但我不确定应该将其放置在何处,以便所有线程都能使用它。也许我需要2个,一个用于
Main
类向
Listener
类发送信号,另一个用于向所有
客户端
类发送信号

谁能帮我一下吗,因为这几乎是这个项目所需基础设施的最后一部分

如果您需要更多信息,我会尽力提供。

更改代码:

while (true)
    {
        _allDone.Reset();
        listener.BeginAccept(new AsyncCallback(AcceptCallBack), listener);
        _allDone.WaitOne();
    }
在你的类中有一些你可以设置的变量

while (this.Work)
    {
        _allDone.Reset();
        listener.BeginAccept(new AsyncCallback(AcceptCallBack), listener);
        _allDone.WaitOne();
    }

当您想停止侦听器时,只需将Work属性设置为false。

您是否考虑过重写该部分并去掉所有线程,并遵循最佳做法使用socket和线程池,然后选择包含新数据的套接字?让事情变得容易多了。如果你在任何地方都使用asyc方法,那么为什么你需要额外的线程呢?一个合适的Telnet服务器在所有客户端断开连接之前不会终止。实现一个对任何想使用您的服务器的人来说都是如此破坏性的功能没有多大意义。或者只启动一个线程来调用BeginReceive()。@TomTom你有这样的例子吗?我参与这个项目已经有一段时间了,所以TelNet的基础工作已经完成了。我不太了解TelNet,所以我只是用我所拥有的来运行。@HansPassant我知道它不应该在所有客户端断开连接之前终止,但这是项目的一项要求。此外,如果在连接设备时程序需要关闭(例如放在抽屉中的某个地方),则需要该选项,这样我就不会有额外的线程负载。如果你这样做,请确保这一点。工作标记为volatile这似乎是我见过的一些示例,但这只会影响侦听器线程,那么所有的客户端线程呢?
while (this.Work)
    {
        _allDone.Reset();
        listener.BeginAccept(new AsyncCallback(AcceptCallBack), listener);
        _allDone.WaitOne();
    }