【问题标题】:Thread will not close, doesn't seem to reach changed variable线程不会关闭,似乎没有达到改变的变量
【发布时间】:2014-04-11 12:03:24
【问题描述】:

我正在开发一款多人游戏,使用 lidgren 库进行联网。

我目前在读取从我的服务器发送的消息的函数时遇到问题。 函数如下所示:

public class Client
{
    /* code omitted */

    public void ReadMessage()
    {   
        //Read Messages
        while (running)
        {
        Debug.Log("InREAD");
           //wClient is a NetClient (lidgren library)
        NetIncomingMessage msg;
        while ((msg = wClient.ReadMessage()) != null)
        {

            switch (msg.MessageType)
            {
                case NetIncomingMessageType.Data:

                    if (msg.ReadString().Contains("Position"))
                    {
                        Debug.Log("Hej");
                        /*string temp = msg.ReadString();
                    string[] Parts = temp.Split(" ");

                    int x = int.Parse(Parts [1]);
                    int y = int.Parse(Parts [2]);
                    int z = int.Parse(Parts [3]);*/


                        //set player position to xyz values below
                    } else if (msg.ReadString().Contains("Instantiate"))
                    {
                        Debug.Log("Instantiate");
                        /* string temp = msg.ReadString();
                        string[] Parts = temp.Split(" ");*/

                    }
                    break;

            }
        }
        }
    }
}

如您所见,当 bool 运行为 true 时会运行一个 while 循环(是的,我在声明时将其设置为 true。)。

现在,在连接按钮等的 GUI 类中,我有一个对 OnApplicationQuit 的函数调用,如下所示:

void OnApplicationQuit()
{
    client.running = false;
    client.Disconnect();
    Debug.Log(client.running);
    Debug.Log("Bye");
}

但是,运行的变化并没有到达线程(我相信线程是在变量的缓存版本上运行的?)。所以我的问题是,当程序关闭时如何使while循环停止? (我试过在OnApplicationQuit()中的线程上调用.Abort()函数,但是也没用。

另外,我知道除非您需要,否则通过网络发送字符串效率不高(所以无需告诉我!)

【问题讨论】:

    标签: c# multithreading networking unity3d


    【解决方案1】:

    只是猜测(因为我不知道库lidgren):您的线程是否可能因为您没有收到来自客户端的任何消息而被困在调用wClient.ReadMessage() 中?如果wClient.ReadMessage() 是一个阻塞调用,那么结果行为将是您描述的行为。

    此外:即使调用Thread.Abort() 也不起作用,因为线程处于睡眠状态(因为它正在等待来自网络连接的某些内容):一旦您的wClient.ReadMessage() 返回,该线程将被中止。查看 MSDN here 它告诉“如果在托管线程执行非托管代码时调用 Abort,则在线程返回托管代码之前不会抛出 ThreadAbortException”,这正是您的情况假设ReadMessage() 在某些时候会执行系统调用,只是为了等待来自底层套接字的一些数据。

    【讨论】:

    • 断开调用不应该中断ReadMessage函数吗?
    • @ThaMe90:我不知道...如前所述,我不知道lidgren 是如何实现的,您的问题的答案取决于ReadMessage()lidgren 中的实现方式跨度>
    【解决方案2】:

    您必须致电client.Shutdown()

    【讨论】:

    • 这没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。
    • 糟糕,你是对的;我没有仔细阅读这个问题。但是 NetClient.ReadMessage() 不会阻塞,退出应用程序时应该调用 Shutdown() (因为它会结束网络线程)。
    猜你喜欢
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    • 2015-06-17
    • 2022-01-14
    • 2014-04-11
    • 2021-03-16
    • 1970-01-01
    相关资源
    最近更新 更多