用户调用时关闭线程

时间:2014-06-02 09:47:42

标签: c# multithreading

我有一个简单的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.
}

监听器类(从主UI类创建的线程):

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

客户端类(从Listener类创建的线程):

public TelNetClient(Socket socket, string clientName)
{
    Thread thread = new Thread(() => TelNetClientStart(socket, clientName));
    thread.Start();
}

private void TelNetClientStart(Socket socket, string clientName)
{
    DeviceConnection deviceConnection = new DeviceConnection();

    this.ClientName = clientName;
    this.State = new StateObject();
    this.State.WorkSocket = socket;

    Send(this.State, "Welcome...");

    this.State.WorkSocket.BeginReceive(this.State.Buffer, 0, StateObject.BufferSize, 0,
        new AsyncCallback(ReadCallBack), this.State);
}

请记住,缺少相当数量的代码,因此如果存在未声明的变量或类似的变量,请忽略它们。我只是不想放入大量不相关的代码。

我见过使用ManualResetEvent的示例,这似乎是我需要做的事情,但是我不知道在哪里放置它以便所有线程都能解决它。也许我需要2,一个用于Main类来表示Listener类,并从那里发出另一个来表示所有Client类?

任何人都可以帮助我,因为它几乎是该项目所需的基础设施的最后一部分。

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

1 个答案:

答案 0 :(得分:2)

更改代码:

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。