Событие генерируется постоянно, код замедляется.Как справиться с этим с потоками? - PullRequest
2 голосов
/ 21 марта 2012

Я знаю, что есть лучший способ сделать это. Я довольно новичок в многопоточном программировании, однако повышение моего события в новом потоке, подобном приведенному ниже коду, позволяет моему приложению получать более высокий FPS с Kinect.

Когда объект моего класса KinectService инициализируется, внутри этого метода я делаю это:

Thread t = new Thread(() =>
{
    sensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(sensor_AllFramesReady);
    KinectSensor.KinectSensors.StatusChanged += new    EventHandler<StatusChangedEventArgs>(Kinects_StatusChanged);
});
t.Start();

Который в свою очередь вызывает этот метод:

void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e) 
{
    using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
    {
        if (depthFrame == null)
        {
            return;
        }

        byte[] pixels = GenerateColoredBytes(depthFrame);            
        int stride = depthFrame.Width * 4;
        BitmapSource test = BitmapSource.Create(depthFrame.Width, depthFrame.Height,
                    96, 96, PixelFormats.Bgr32, null, pixels, stride);

        test.Freeze();

        if (FrameChanged != null)
        {
            FrameChanged(test);
        }
    }    
}

FrameChanged (test) передает вновь созданное растровое изображение обратно в модель представления, которая затем обновляет источник изображения. Это ужасный способ сделать это? Выдавать событие своим собственным потоком кажется неправильным, однако это заставляет мое приложение работать намного быстрее. Есть указатели?

1 Ответ

0 голосов
/ 17 апреля 2012

События генерируются в том же потоке, который их вызвал, и в документации нет ничего, что KinectSensor.AllFramesReady могло бы сказать иначе.

Таким образом, в вашем коде датчик. AllFramesReady не будет запускать другое событие, пока ваш обработчик события (sensor_AllFramesReady) не вернется.

Лучший способ сделать это возможно - это изменить ваш обработчик событий, чтобы он порождал поток и немедленно возвращался. * 1009 Т.е. *

void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)  
{
    var frameReadyThread = new Thread(() =>
    using (DepthImageFrame depthFrame = e.OpenDepthImageFrame()) 
    {
        //
    }
    frameReadyThread.Start();
}

Вам потребуется выполнить некоторую синхронизацию, хотя внутри frameReadyThread, чтобы убедиться, что следующее верно,

  1. Кадры не обрабатываются не по порядку, вы не хотите Кадр 1 до Обновление после Кадр 2
  2. Кадры отбрасываются, когда они больше не выполняют полезную работу, а не крадут ЦП.
  3. Если вы реализуете свой собственный диспетчер потоков, который вы масштабируете в соответствии с машиной, на которой вы находитесь. Например, если у вас есть доступ к 8 ядрам, а код вашего обработчика связан с процессором, маловероятно, что вы получите какую-либо выгоду, если у вас более 8 потоков.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...