意外的“;无法访问已处理的对象“”;在清理方法中

本文关键字:方法 访问 意外 处理 对象 | 更新日期: 2023-09-27 17:59:51

当我关闭WPF应用程序时,我面临着一个令人困惑的已处理对象问题。如果你发现我的逻辑有任何错误,请指出。

我有一个带有update()方法的ColorManager类,如下所示。

public void Update(ColorImageFrame frame)
{
    byte[] pixelData = new byte[frame.PixelDataLength];
    frame.CopyPixelDataTo(pixelData);
    if (Bitmap == null)
    {
        Bitmap = new WriteableBitmap(frame.Width,
                                     frame.Height,
                                     96,
                                     96,
                                     PixelFormats.Bgr32,
                                     null);
    }
    // draw bitmap
    RaisePropertyChanged(() => Bitmap);   
}

我在一个单独的线程中运行这个方法。在我的MainWindow.xaml.cs中,我有以下内容:

    private void Initialise()
    {
        if (kinectSensor == null)
            return;
        // start kinect sensor        
        kinectSensor.Start();
        updateColourStreamThread = new Thread(new ThreadStart(colorStreamDisplay));
        updateColourStreamThread.Name = "updateColourStreamThread";
        updateColourStreamThread.Start();
        // ...some more codes
     }
        void colorStreamDisplay()
        {
            while(isDisplayActive)
            {
                using (var frame = kinectSensor.ColorStream.OpenNextFrame(500))
                {
                    if (frame == null) continue;
                    if (displayDepthStream) continue;
                    Dispatcher.Invoke(new Action(() => colorManager.Update(frame)));
                }
            }
        }

我在MainWindow.xaml.cs中有以下方法来在单击关闭按钮后进行清理。

    private void Clean()
    {
        isDisplayActive = false;
        // some other codes
        if (kinectSensor != null)
        {
            updateColourStreamThread.Abort();
            updateDepthStreamThread.Abort();
            updateSkeletonStreamThread.Abort();
            kinectSensor.Stop();
            kinectSensor = null;
            Console.WriteLine("Closed successfully");
        }

单击关闭按钮后,我的应用程序在frame.CopyPixelDataTo(pixelData);上抛出"无法访问已处理的对象"。

我将bool值切换为false以停止循环,然后中止线程并停止kinect设备。

我错过了什么?

意外的“;无法访问已处理的对象“”;在清理方法中

当您将布尔值设置为false时,应用程序将退出while循环:

1) 将bool设置为假

        isDisplayActive = false;

2) 将退出此循环:

        while(isDisplayActive)
        {
            using (var frame = kinectSensor.ColorStream.OpenNextFrame(500))
            {
                if (frame == null) continue;
                if (displayDepthStream) continue;
                Dispatcher.Invoke(new Action(() => colorManager.Update(frame)));
            }
        }

3) 所以你的框架也会超出范围。因此,它将被处理。。。

using (var frame = kinectSensor.ColorStream.OpenNextFrame(500))

4) 而您的主线程还没有执行Thread.Abort

5) 因此,您的CopyPixelDataTo将在已处理的frame对象上执行。

frame.CopyPixelDataTo(pixelData);

6) 和kaboom,你有你的对象处理异常。


线程。中止是个坏主意

你永远不知道执行线程在执行之前有多远,这可能会导致各种恶劣的副作用。阅读本问答中的更多内容;A: 什么';It’使用Thread.Artrt()有问题

在你的情况下,我会做的是更换

while(isDisplayActive)

while(colorThingyThreadIsBusy)

Thread准备就绪(=完成处理)时,将colorThingyThreadBusy布尔设置为false。

为了优雅地关闭您的应用程序,我会实现CancellationToken,而不是中止线程。