同时为多个线程调用Join

时间:2018-05-22 14:15:49

标签: c# multithreading

我正在用C#编写一个脚本来读取来自多个来源的消息。我有一个函数ReadMessage,它接受​​一个端口字符串并返回一个字符串ID号。问题是,我需要读取十几种不同的连接,并且消息在停止尝试之前有一个10ms的超时计时器并让代码继续。当我有十几个线程等待前一个完成连接的几毫秒时,这会导致帧速率降低。我的线程代码如下:

string threadOneString= null;
Thread ThreadOne;
//Repeat for 11 more threads
void Update () {
    ThreadOne = new Thread(
        () =>
        {
            threadOneString = ReadMessage(someClass.port);
        });
    ThreadOne.Start();
//Repeat for 11 more threads
}

void LateUpdate () {
    ThreadOne.Join();
    //Repeat for 11 more threads

    UpdateClass(threadOneString);
    //Repeat for 11 more threads

    UpdateTextDisplay(); //Just updates a Unity Text object
}

我的ReadMessage代码以防万一。

private string ReadMessage(string port) //Change this name to ReadButtonPress
    {
        string fullMessage = "";
        someStruct parsedMessage;
        var timeout = new System.TimeSpan(0, 0, 0, 0, 10); // Less than 10 and it starts to miss most messages, ideally this would be a bit higher
        string connectionString = PROTOCOL + CONTROLLER_IP + ":" +  port;

        AsyncIO.ForceDotNet.Force();     
        using (var subSocket = new SubscriberSocket())
        {
            subSocket.Connect(connectionString);
            subSocket.Subscribe("");

            subSocket.TryReceiveFrameString(timeout, out fullMessage);
            UnityEngine.Debug.Log("Message: " + fullMessage);

            subSocket.Close();
        }
    // Some message parsing and checking...
    return parsedMessage.someString;
}

我想做什么,但我不知道是否可能,是同时为每个线程调用联接,而不是调用一个,等待,然后调用下一个。线程不会相互影响,所以我希望这是可能的。如果没有,我将非常感谢另一种解决方案或建议。

编辑:澄清正在发生的事情。当我只运行几个线程时,我的FPS为65-70。当我运行所有12个线程时,我的FPS下降到~50,我有60 FPS的硬性要求。

3 个答案:

答案 0 :(得分:0)

感谢这里的一些反馈,我不再每次更新都会创建套接字。相反,我在Start()中创建套接字,只是从类中的公共函数中读取我需要的东西。我的代码基于https://stackoverflow.com/a/14797475/8635796

不要做我做的事情,并且每Update()重新创建完全相同的线程和套接字。事后看来,这是一个非常糟糕的选择。

答案 1 :(得分:-1)

改为使用任务,并将它们放入列表中。

var myTasks = new List<Task>();
Task allUpdateTasks;
...
void Update () {
    myTasks.Add(
        Task.Factory.StartNew(() =>
        {
            threadOneString = ReadMessage(someClass.port);
        }));
//Repeat for 11 more tasks

// Create a single tasks that will hold all tasks above.
allUpdateTasks = Task.WhenAll(myTasks);
}

void LateUpdate() {
    allUpdateTasks.Wait();
...
}

答案 2 :(得分:-1)

定义ManualResetEvent并在获得结果时发出信号,使用WaitHandle.WaitAny可以等待多达64个等待句柄