Kinect for Windows SDK + XNA

imageI have seen a few people talk about using the Kinect for Windows SDK with XNA lately, and many of those projects aren't using the SDK how it's intended to be used from a framework such as this.

When I had a hand in working on the managed SDK, I made a point that the API should allow for both an "eventing" model, and a polling model.  In the land of WPF and WinForms, an eventing model makes perfect sense.  In these frameworks, the SDK is intended to be used thusly:

private Nui.Runtime _kinect = Nui.Runtime.Kinects[0];

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    _kinect.DepthFrameReady += DepthFrameReady;
    _kinect.SkeletonFrameReady += SkeletonFrameReady;
}

void DepthFrameReady(object sender, ImageFrameReadyEventArgs e)
{
    // do something with the depth frame
}

void SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
    // do something with the skeleton frame
}

But, in the land of XNA, where all of your code is shared between the Update and Draw methods, and where events don't really exist in the normal flow of things, trying to synchronize the Kinect events and the data they provide with the Update and Draw loop can be difficult, and can lead to conditions where data is being updated from an event while you're touching it in the Update method.  Sure, you could use locks to help synchronize things, but there's an easier way.

To help with this, the API contains methods to directly poll for the latest data, such as the current depth frame or skeleton frame.  These methods can be used as shown:

private Runtime _kinect = Runtime.Kinects[0];
private SkeletonFrame _skeletonFrame;
private ImageFrame _depthFrame;

protected override void Update(GameTime gameTime)
{
    _skeletonFrame = _kinect.SkeletonEngine.GetNextFrame(0);
    _depthFrame = _kinect.DepthStream.GetNextFrame(0);

    base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
    // do something with _skeletonFrame and/or _depthFrame
    // such as, draw it to the screen
    
    base.Draw(gameTime);
}

So, if you're using XNA in tandem with the Kinect for Windows SDK, be sure to use the API as it was intended.  It will likely save you some debugging headaches later on.