意外的“;无法访问已处理的对象“”;在清理方法中
本文关键字:方法 访问 意外 处理 对象 | 更新日期: 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,而不是中止线程。