1

はじめに: モーション トラッカーを使用して人間の運動系を分析するソフトウェアを開発しています。現在、xsens からハードウェアを実装し、SDK を使用してワイヤレス センサーからデータを受信して​​います。SDK は、現在利用可能な xyz 軸データ (簡略化) を受け取るために呼び出す「getData」メソッドを備えた COM インターフェイスを提供します。getData を呼び出さない場合、その「ビート」をスキップするため、データが失われ、ハードウェア/SDK にキャッシュがありません。

問題: 私の問題は、少なくとも 75Hz、できればもう少し高い速度でデータを取得する必要があることですが、75 は許容範囲ですが、現在、1 秒あたりわずか 20 信号に急速に低下しています... 処理を削除するとビット (以下のサンプルを参照) 完璧なサンプル レートが得られたので、デキューが原因でエンキューが一時停止していると思います。または、「重い」CPU 負荷が原因で、すべてのスレッドが待機しています。実際に何が原因なのかを突き止める方法がわかりません。プロファイラー (EQATEC) は、しばらくすると「GetData」メソッドに時間がかかっていることを示しているだけです。

質問: これを達成するために使用する最適な手法は何ですか? 「読み取り」スレッドが中断/ブロックされるのはなぜですか? 途中で中断せずに読みたいという方も多いのではないかと思いますが、ググって2週間経ちましたが、どうやら正しい単語が見つからないみたいです。

お知らせ下さい。

ありがとう

MultiMedia タイマー ( http://www.codeproject.com/Articles/5501/The-Multimedia-Timer-for-the-NET-Framework ) と BackgroundWorkerを使用した簡略化されたコード サンプル、バージョン 4

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;
  }
}
4

1 に答える 1

2

私はここで問題を見ています

 _backgroundProcessDataThread.Start();
 while (!_backgroundProcessDataThread.IsAlive){}

_backgroundGetDataThread.Start();
while (!_backgroundGetDataThread.IsAlive) {}

さて、ここで無限ループが発生していることがわかります。2 番目のスレッドは、最初のスレッドが作業を終了した後にのみ開始されます。つまり、最初のスレッドが完了します。これは決して理想的なモデルではありません。

申し訳ありませんが、後で問題を認識しました。

問題は、_backgroundGetDataThread が _backgroundProcessDataThread の処理が完了した後にのみ開始されることです。

于 2013-03-22T12:32:14.007 に答える