说明: 我正在开发使用运动跟踪器分析人体运动系统的软件。目前,我正在使用xsens的硬件并使用他们的SDK从他们的无线传感器接收数据。 SDK提供了一个带有“getData”方法的COM接口,您可以调用该方法接收当前可用的xyz轴数据(简化)。如果您不调用getData,则跳过“beat”,这样您就会丢失数据,硬件/ SDK中没有缓存。
问题: 我的问题是我需要以至少75Hz的速率获取数据,最好是多一点,但75可以接受,但我目前正在迅速降至每秒仅20个信号...... 如果我删除处理位(参见下面的示例),我会得到完美的采样率,所以我认为出队导致入队暂停。或者“重”CPU负载导致所有线程等待。我不知道如何弄清楚究竟是什么导致它,分析器(EQATEC)只是显示我的“GetData”方法在一段时间后需要更长的时间。
问题: 用于实现此目的的最佳技术是什么?为什么我的“阅读”线程会被中断/阻止?必须有更多的案例,人们需要在不被打断的情况下阅读某些内容,但我现在已经谷歌了2周,显然我找不到正确的词语。
请告知。
由于
简化代码示例,版本4,使用MultiMedia计时器(http://www.codeproject.com/Articles/5501/The-Multimedia-Timer-for-the-NET-Framework)和BackgroundWorker
public class Sample
{
private MultiMediaTimer _backgroundGetData;
private bool _backgroundGettingData;
private BackgroundWorker _backgroundProcessData;
private ConcurrentQueue<double> _acceleration = new ConcurrentQueue<double>();
private void StartProcess()
{
if (_backgroundGetData == null)
{
_backgroundGetData = new MultiMediaTimer {Period = 10, Resolution = 1, Mode = TimerMode.Periodic, SynchronizingObject = this};
_backgroundGetData.Tick += BackgroundGetDataOnTick;
}
_backgroundProcessData = new BackgroundWorker {WorkerReportsProgress = false, WorkerSupportsCancellation = true};
_backgroundProcessData.DoWork += BackgroundProcessDataOnDoWork;
_backgroundGetData.Start();
}
private void BackgroundProcessDataOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
{
double value;
if (!_acceleration.TryDequeue(out value)) value = 0;
//Do a lot of work with the values collected so far,
//this will take some time and I suspect it's the cause of the delays?
}
private void BackgroundGetDataOnTick(object sender, EventArgs eventArgs)
{
if (_backgroundGettingData) return;
_backgroundGettingData = true;
//123 represents a value I am reading from the sensors using the SDK
double value = 123;
if (value == -1)
{
Thread.Sleep(5);
continue;
}
_acceleration.Enqueue(value);
if (_acceleration.Count < 5) continue;
if (!_backgroundProcessData.IsBusy)
{
_backgroundProcessData.RunWorkerAsync();
}
_backgroundGettingData = false;
}
}
答案 0 :(得分:2)
我在这里看到了问题
_backgroundProcessDataThread.Start();
while (!_backgroundProcessDataThread.IsAlive){}
_backgroundGetDataThread.Start();
while (!_backgroundGetDataThread.IsAlive) {}
嗯,你可以在这里看到你在这里有无限循环,第二个线程只在第一个完成它的工作后才开始。即第一个线程完成。这绝不是理想的模型。
抱歉,我后来认出了这个问题。
问题是,_backgroundGetDataThread只有在_backgroundProcessDataThread完成其工作后才会启动。