Thread.Join() 不会等到线程终止

本文关键字:线程 终止 Join Thread | 更新日期: 2023-09-27 17:56:47

我正在制作一个服务器,当客户端连接时,我创建一个线程,该线程侦听来自客户端的消息,所以基本上只做StreamReader.Readline()
创建此answerListener线程的线程必须等到answerListener线程终止,但它不会等待。

这是我代码
的一部分

            Thread answersListener = new Thread(new ThreadStart(StartListeningAnswers));
            answersListener.Name = Thread.CurrentThread.Name + "_listener";
            answersListener.Start();
            while (player.status.Equals(PlayerStatus.Playing))
            {
                CheckOpponentStatus();
                Thread.Yield();
            }
            DetermineResult(player.status);

            answersListener.Join();
            RuntimeInfo.Instance.playerList.TryDequeue(out player);
            player.Input.Close();
            player.Input.Dispose();
            player.Output.Close();
            player.Output.Dispose();
            player.Socket.Close();
            Console.WriteLine("client " + player.playerID + " disconnected");
            player = null;

这就是StartListeningAnswers()方法的作用:

            while (player.status.Equals(PlayerStatus.Playing))
            {
                answer = player.Input.ReadLine();
                if (answer == null) return;
            }

这是StartListeningAnswers()方法中的一个catch块:

        catch (IOException e)
        {
            Console.WriteLine(player.playerID + " Connected = " + player.Socket.Connected);
            Console.WriteLine("ERROR: ReceiveAnswer from " + player.playerID);
            return;              
        }

当我运行服务器时,我在尝试在StartListeningAnswers()

中执行ReadLine()时出现异常我在控制台输出中有以下顺序:

client 1 disconnected
1 Connected = False

ERROR: ReceiveAnswer from 1

所以我想主线程不会等到玩家发送一些东西,只是继续执行并关闭流。

我做错了什么?

Thread.Join() 不会等到线程终止

你的代码存在一些问题。首先,您没有呼叫Thread.Yield()。而且player.status不是线程安全的 (http://rbwhitaker.wikidot.com/c-sharp-threading)。

但主要问题是player.status永远不会变成PlayerStatus.Playing,所以服务器中的while循环永远不会中断。

我不完全了解上下文和我会建议一种不同的方法来实现这一点,但你可以做一些事情:

public void StartListeningAnswers()
{
    try
    {
        while (player.status.Equals(PlayerStatus.Playing))
        {
            string answer = player.Input.ReadLine();
            if (string.IsNullOrEmpty( answer )) 
                return;
        }
    }
    finally
    {
        player.status = PlayerStatus.Stopped;
    }
}