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

时间:2014-04-05 22:55:17

标签: c# multithreading inputstream streamreader

我正在建立一个服务器,当客户端连接时,我创建了一个线程,它监听来自客户端的消息,所以基本上就是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;
            }

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

        catch (IOException e)
        {
            Console.WriteLine(player.playerID + " Connected = " + player.Socket.Connected);

            Console.WriteLine("ERROR: ReceiveAnswer from " + player.playerID);
            return;              
        }

当我运行服务器时,我在ReadLine()中尝试StartListeningAnswers()时遇到异常 我在控制台输出中有以下顺序:
client 1 disconnected
1 Connected = False
ERROR: ReceiveAnswer from 1

所以我猜主线程不会等到玩家发送内容并继续执行并关闭流。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。首先,您没有电话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;
    }
}