【发布时间】:2016-02-01 04:34:45
【问题描述】:
好的,这个标题可能含糊不清,但请允许我解释一下。
我正在处理一个大列表,其中包含数百条要作为字节数组发送到 CAN 总线的消息。这些消息中的每一个都有一个 Interval 属性,详细说明了消息必须发送的频率,以毫秒为单位。但我会回到那个。
所以我有一个线程。线程循环遍历这个巨大的消息列表,直到停止,主体大致如下:
Stopwatch timer = new Stopwatch();
sw.Start();
while(!ShouldStop)
{
foreach(Message msg in list)
{
if(msg.IsReadyToSend(timer)) msg.Send();
}
}
这很有效,在遵守消息对象的间隔方面具有惊人的准确性。但是,它占用了整个 CPU。问题在于,由于消息的数量巨大以及 CAN 总线的性质,通常在线程必须发送另一条消息之前不到半毫秒。永远不会出现线程能够休眠超过 15 毫秒的情况。
我想弄清楚的是,是否有一种方法可以让线程暂时阻塞或让出,从而让处理器休眠并节省一些周期。如果我尝试将工作分成每条消息的线程,我会得到任何准确性吗?还有其他我没有看到的方法吗?
编辑:值得一提的是,Message 的 Interval 属性不是绝对的。只要线程继续发送消息,接收者就应该很高兴,但如果线程由于更高优先级的线程窃取其时间片而定期休眠,例如 25 毫秒,它可能会为接收者发出危险信号。
【问题讨论】:
-
只需在
while()内添加一个Thread.Sleep(0)即可使其播放不错。如果这是一个 GUI 应用程序,那么你的while()不应该在主线程上 -
@Micky Sleep(0) 将释放剩余的时间片 - 因此线程可能被安排在大约 7-10 毫秒(平均)内执行,因此最多发送 20 条消息(如" 不到半毫秒...发送另一条消息")
-
@AlexeiLevenkov 听起来是时候打破 Arduino 和分线板了! xkcd.com/730
-
基于更新后的常规 Sleep(0) 可能是可以接受的。试试看。
-
是的,经过考虑,我想我愿意放弃几毫秒的准确性损失。 Sleep(0) 应该可以解决我的问题。
标签: c# multithreading can-bus