事件不断提高,代码速度变慢。如何用线程处理它?

时间:2012-03-21 00:55:45

标签: c# multithreading events

我知道有更好的方法可以做到这一点。我对多线程编程很新,但是在一个新线程上提高我的事件,如下面的代码允许我的应用程序使用Kinect获得更高的FPS。

当我的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)将新创建的位图传递回viewmodel,然后viewmodel更新图像源。这是一种可怕的方法吗?给一个事件它自己的线程感觉不对,但它使我的应用程序运行更快。有什么指针吗?

1 个答案:

答案 0 :(得分:0)

事件是在调用它们的同一个线程上触发的,KinectSensor.AllFramesReady的文档中没有任何内容可以说明。

因此,在您的代码sensor.AllFramesReady中,在您的事件处理程序(sensor_AllFramesReady)返回之前,它不会触发另一个事件。

更好的方法可能是更改事件处理程序以生成线程并立即返回。即。

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

您需要在frameReadyThread中进行一些同步,以确保以下内容为真,

  1. 不按顺序处理帧,您不希望第1帧 更新 第2帧
  2. 如果框架不再执行有用的工作而不是窃取CPU,则会放弃框架。
  3. 如果您正在实施自己的线程调度程序,则可以适当地扩展到您所在的计算机。例如,如果您可以访问8个内核,并且您的处理程序代码受CPU限制,那么如果您的线程数超过8个,则不太可能看到任何好处。