我在Kinect SDK
应用程序中使用WPF
并使用DepthFrameReady
事件进行操作。为了避免用户界面阻止我创建了事件async
和即时等待"进行数据操作的函数。
立即在visual studio的输出窗口中获取消息:
警告:未放置imageFrame实例
我尝试了很多东西来处理DepthImageFrame
(把逻辑置于using
块内,当异步函数结束时回调等等......)但是在第一次调用之后它发送的是null,所以...
在async / await事件中处理对象的唯一方法是什么?。
MyWindow.xaml.cs
private async void KinectSensorFound_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
// as suggested in Zoran Answer
await Task.Run(() =>
{
using (DepthImageFrame DataDepthImageFrame = e.OpenDepthImageFrame())
{
UpdateUserDepthInfo(DataDepthImageFrame);
}
});
}
public void UpdateUserDepthInfo(DepthImageFrame DataDepthImage)
{
var TimeNow = DateTime.Now;
if ((DateTime.Now - PreviusTime).Milliseconds <= 50)
return;
syncronizationContext.Post(new SendOrPostCallback(o =>
{
if (chckbxDepthImage.IsChecked == true)
{
chckbxColorImage.IsChecked = false;
// This method is called in my bussines logic to do a transformation with the frame
BitmapSource DepthBitMapSource = Controller.getInfoOfDepthUser(DataDepthImage);
DepthCanvas.Background = new ImageBrush(DepthBitMapSource);
}
else
{
DepthCanvas.Children.Clear();
DepthCanvas.Background = new SolidColorBrush(Colors.Transparent);
}
DepthUserInfo = Controller.DoGetInfoDepthUser(DataDepthImage);
lblDepthUser.Content = string.Format("{0:0.00} mts", DepthUserInfo / 1000);
}), DataDepthImage);
PreviusTime = TimeNow;
}
KinectHelper.cs
public BitmapSource getBitmapOfDepth(DepthImageFrame DataImageFrame)
{
DepthImagePixel[] ImageDepth = new DepthImagePixel[0];
int DepthDistance;
depthReturnStruct DepthReturn = new depthReturnStruct();
if (DataImageFrame != null)
{
ImageDepth = new DepthImagePixel[DataImageFrame.PixelDataLength];
DataImageFrame.CopyDepthImagePixelDataTo(ImageDepth); // exception here
//... other code
}
return bitmapDepth;
}
答案 0 :(得分:0)
我的印象是你在混合责任。为了清楚起见,每个对象都应该拥有一个所有者 - 实例化它并将其处理掉的所有者。在您的解决方案中,这些是两个实体 - 构造DataDepthImageFrame
的事件处理程序和执行工作的任务。
在我看来,启动任务的功能不应该构建图像框架,而是为它准备工厂函数。这将允许任务实例化和处置对象。通过这种方式,任务将完全负责该对象。
当然,如果您计划在关闭中捕获工厂,那么您甚至不需要它 - 您可以捕获事件参数e
并直接在任务中使用它们。
private async void KinectSensorFound_DepthFrameReady(
object sender, DepthImageFrameReadyEventArgs e)
{
await Task.Run(
() =>
{
using (DepthImageFrame DataDepthImageFrame = e.OpenDepthImageFrame())
{
UpdateUserDepthInfo(DataDepthImageFrame)
}
});
}
我无法重现您的场景,但我相信当任务开始运行时,来自事件参数的图像帧将在另一个线程中打开。