0

i must show sequence of image in a new thread because otherwise kinect lost frame for the complexity of operations. I have tried so:

 using (BodyFrame bodyframe = e.FrameReference.AcquireFrame())
            {
                if (bodyframe != null)
                {
                    if (this.bodies == null)
                    {
                        this.bodies = new Body[bodyframe.BodyCount];
                    }
                    //the first time getandrefreshbodydata is called, kinect will allocate each body in the array.
                    //as long as those body objects are not disposed and not set to null in the array,
                    //those body objects will be re-used.
                    bodyframe.GetAndRefreshBodyData(this.bodies);
                    dataReceived = true;
                }
                else Console.WriteLine();
            }
            BodyCustom[] bodiesCustom = deserialize(directoryTxt[frameCount]);

            sw.WriteLine("Frame " + frameCount);
            if (dataReceived)
            {
                sw.WriteLine(dataReceived);
                ThreadPool.QueueUserWorkItem(showImage, frameCount);
..............

And:

private void showImage(Object frameCount)
    {

       imageReference.Source = new BitmapImage(new Uri(@directoryJpg[(int)frameCount]));
    }

but i have

An unhandled exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll 
Additional information: Unable to access the object from the calling thread because that object is owned by another thread.

I think that the error depends on the object imageReference because i use it elsewhere, but also by commenting it i obtain this error. Why?

I'm using Image Class (System.Windows.Controls)

luca
  • 3,248
  • 10
  • 66
  • 145

1 Answers1

0

The problem is that you can't update the UI on a background thread. (Also it helps if you translate the error message to English, I would say most people on here don't understand Italian.)

You'll need to marshal back onto the UI thread to change the image.

First you'll need to store off the Current Synchronization Context.

This is easiest done in the constructor.

public class MyObject 
{
  private SynchronizationContext CurrentSynchronizationContext;

  public MyObject()
  { 
    CurrentSynchronizationContext = System.Threading.SynchronizationContext.Current;
  }
}

Next, in your ThreadPool.QueueUserWorkItem operation (whether that is a delegate, or a lambda), add something like this:

public void SomeMethodThatDoesSomethingOnABackgroundThread()
{
  ThreadPool.QueueUserWorkItem(() => 
  { 
    // Do some operation that is going to take some time, or can't be done on the UI thread.
    Thread.Sleep(100000); 

    // Operation is complete, let's return the result back to the UI.
    CurrentSynchronizationContext.Post(() => 
    {
      // Change the UI, send a messagebox to the user, change the image. Whatever you need.
      // Also the return isn't necessary, it's just signifying that the method is done. 
      return; 
    },null); 
  }
}
Cameron
  • 2,574
  • 22
  • 37
  • i have tried your method but i have 2 exception in ThreadPool.QueueUserWorkItem(() because have 0 argoument and in CurrentSynchronizationContext.Post(( because have 2 arguments – luca Nov 04 '14 at 14:03
  • I have corrected the `CurrentSynchronizationContext.Post()` implementation. The `ThreadPool.QueueUserWorkItem()` implementation is using a lambda. If you also prefer you can write out a method and just pass the method name. Sorry if this is a little complex, it is something strange to grasp. Let me know if you need an example. – Cameron Nov 04 '14 at 15:45
  • thanks, now i don't have error but the kinect anyway lost frame if show the image,as before – luca Nov 04 '14 at 16:36