我正在用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的硬性要求。
答案 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个等待句柄