Multithreading 错误:调用线程无法访问此对象,因为其他线程拥有它-Kinect
所以我尝试用SDK编程kinect传感器。这是代码Multithreading 错误:调用线程无法访问此对象,因为其他线程拥有它-Kinect,multithreading,exception,sdk,kinect,Multithreading,Exception,Sdk,Kinect,所以我尝试用SDK编程kinect传感器。这是代码 public partial class MainWindow : Window { bool mirror=false; bool displayActive = true; int redOffset; int greenOffset; int blueOffset; WriteableBitmap colorImageBitmap = null; KinectSensor myKin
public partial class MainWindow : Window
{
bool mirror=false;
bool displayActive = true;
int redOffset;
int greenOffset;
int blueOffset;
WriteableBitmap colorImageBitmap = null;
KinectSensor myKinect;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
kinectVideo.Source = colorImageBitmap;
myKinect = KinectSensor.KinectSensors[0];
if (KinectSensor.KinectSensors.Count == 0)
{
MessageBox.Show("No Kinects detected", "Camera Viewer");
Application.Current.Shutdown();
}
myKinect.ColorStream.Enable();
myKinect.Start();
Thread updateVideoThread;
updateVideoThread = new Thread(new ThreadStart(videoDisplay));
updateVideoThread.Start();
}
void videoDisplay()
{
while (displayActive)
{
using (ColorImageFrame colorFrame = myKinect.ColorStream.OpenNextFrame(10))
{
if (colorFrame == null) continue;
byte[] colorData = new byte[colorFrame.PixelDataLength];
colorFrame.CopyPixelDataTo(colorData);
//----------------------------Methodos 2 for image color adjustment------------------------------------------------------------------------------------
updateColor(colorData);
//----------------------------Methodos 1 for mirror------------------------------------------------------------------------------------
if (mirror) { reflectImage(colorData, colorFrame.Width, colorFrame.Height); }
//----------------------------Methodos 2 for update image------------------------------------------------------------------------------------
kinectVideo.Source = colorImageBitmap;
if (colorImageBitmap == null)
{
this.colorImageBitmap = new WriteableBitmap(colorFrame.Width,
colorFrame.Height,
96, // DpiX
96, // DpiY
PixelFormats.Bgr32,
null);
}
this.colorImageBitmap.WritePixels(new Int32Rect(0, 0, colorFrame.Width, colorFrame.Height),
colorData, // video data
colorFrame.Width * colorFrame.BytesPerPixel, // stride,
0 // offset into the array - start at 0
);
}
}
}
在“kinectVideo.Source=colorImageBitmap;”行中,is给了我一个异常,该异常表示“调用线程无法访问此对象,因为另一个线程拥有它。”。我不明白为什么。我是C#和Visual Studio编程新手。我只有一个线程,所以我不知道为什么会出现异常。有什么帮助吗?好的,所以基本上你是在尝试从一个不是主线程的线程更新UI,如果不调用一些描述,这永远不会起作用 查看此线程上的答案,它看起来与您遇到的问题完全相同
根据这些答案,您应该将videoDisplay()中的代码更改为:
...
Action action = delegate { kinectVideo.Source = colorImageBitmap; };
kinectVideo.Dispatcher.Invoke(action);
if (colorImageBitmap == null){
...
如果这不起作用,请尝试:
...
colorImageBitmap.Freeze();
Action action = delegate { kinectVideo.Source = colorImageBitmap; };
kinectVideo.Dispatcher.Invoke(action);
if (colorImageBitmap == null){
...
考虑到您还使用了kinectVideo.Source=colorImageBitmap这一行;在Window_-Loaded方法中,您可能还需要在那里使用.Freeze()
我对XAML和Freeze()不太熟悉,但由于colorImageBitmap在这两种方法中都没有初始化,因此可能会给您带来其他问题。对您来说,使用可能是一个更好的选择,但它可能会影响内存。我找到了问题的答案。这就是我所做的 1) 声明了一个线程
Private Backgroundworker _worker;
2) 创建一个实例,订阅DoWork事件,并启动新线程
this._worker=new BackgroundWorker();
this._worker.DoWork += Worker_DoWork;
this._worker.RunWorkerAsync();
3) 编写事件处理程序
private void Worker_DoWork(object sender, DoWorkEventArgsn e) { ... }
4) 然后把这些代码放在创建位图的地方和重写位图的地方
this.ColorImageElement.Dispatcher.BeginInvoke(new Action(() => { ... }
你有两条线。运行应用程序的主线程和创建用于运行videoDisplay的线程。kinectVideo对象来自哪里?我明白。因此,如果我得到了正确的答案,当我为videoDisplay创建线程时,我创建的线程(updateVideoThread)和程序的主线程都试图运行该方法,以便调用异常?kinect对象来自这行代码---->使用Microsoft.kinect;With更向上,dint在这里复制了它。这不是因为他们都试图运行该方法,可能是kinectVideo对象属于主线程。kinectVideo是什么类的实例,它是在哪里创建的?它的命名方式看起来像是一个变量,我在Microsft.Kinect中看不到任何名为kinectVideo的静态类。它是表单上的对象还是什么?首先,我要说这是一个WPF项目。其次,这是表单上的一个对象。更具体地说,这是XAML thaτ中的圆锥体创建对象-->“”