我正在寻找Kinect v2 SDK中的MultiSourceFrameArrived事件的一些帮助。
以下是有问题的方法:
private async void _reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
{
MultiSourceFrame multiSourceFrame = e.FrameReference.AcquireFrame();
using (var colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame())
{
if (colorFrame != null)
{
_writeableBitmap.Lock();
colorFrame.CopyConvertedFrameDataToIntPtr(
_writeableBitmap.BackBuffer,
(uint)(_colorFrameDescription.Width * _colorFrameDescription.Height * _colorFrameDescription.BytesPerPixel),
ColorImageFormat.Bgra);
_writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, _writeableBitmap.PixelWidth, _writeableBitmap.PixelHeight));
_writeableBitmap.Unlock();
reflectionOverlayControl.ReflectionImageSource = _writeableBitmap;
}
}
using (var bodyFrame = multiSourceFrame.BodyFrameReference.AcquireFrame())
{
if (bodyFrame != null)
{
Body body = JointHelpers.FindClosestBody(bodyFrame);
if (body != null)
{
if (body.IsTracked)
{
Dictionary<BodyComponentType, BodyComponent> bodyComponentDictionary = BuildBodyComponentDictionary(body);
foreach (BodyComponent bodyComponent in bodyComponentDictionary.Values.OrderBy(x => x.BodyComponentType))
{
bodyComponent.Generate(_writeableBitmap, _coordinateMapper, FrameType.Color, 25);
if (!_isRunningFiltering)
{
_isRunningFiltering = true;
try
{
await Task.Run(() =>
{
bodyComponent.RunFunFiltering();
});
}
finally
{
_isRunningFiltering = false;
}
}
}
reflectionOverlayControl.UpdateValues(
bodyComponentDictionary,
GetFullBodyComponent(body));
}
}
}
}
}
现在,请允许我解释一下:
下一位是我需要帮助的地方!
RunFunFiltering方法是一种密集型处理方法,在运行时会创建一个冻结我的UI的阻塞语句。这会使我的彩色帧视频输入非常跳跃!此RunFunFiltering方法需要设置一些BodyComponent类的属性,例如矩形应显示的颜色,其中ReflectionImageSource中的白色像素数,以及使用第一个ReflectionImageSource的一部分设置另一个可写位图。长方形。
由于此对象现在已完成,并且已设置所有属性(并且已对字典中的每个BodyComponent执行此操作),我在视图上运行UpdateValues方法,该方法在屏幕上的BodyComponent类中显示有趣的内容对我来说。
根据@sstan在这篇文章中的一些建议:Async Await to Keep Event Firing
我扔了一个Task.Run()块。但是,这似乎没有释放我的UI,我仍然看到一个跳跃的图像。奇怪的是在那个计时器例子中,它完美地工作!我在这里有点不知所措。
我是一个有异步功能的初学者,但我真的很想了解你的解决方案。如果您能对代码提供解释,我将非常感激!
更新
我已经能够识别出获取框架的using语句在将其放置在Task.Run调用之外时阻止了UI。
我不能只使用块异步运行整个BodyFrame,因为我需要第一个“生成”函数来始终发生,而不是重处理线程的一部分。两个使用积木似乎不优雅,而是在地毯下推动我的问题......
答案 0 :(得分:0)
根据您的评论我理解以下内容:
Task taskFunFiltering = null;
private async Task ProcessFrame(...)
{ // a new frame is arrived
DoSomeProcessing(...);
// only start a new run fun filtering if previous one is finished
if (taskFunFiltering == null || taskFunFiltering.IsCompleted)
{ // start a new fun filtering
// don't wait for the result
taskFunFiltering = Task.Run( () => ...);
}
}
private async Task RunFunFiltering(...)
{
// do the filtering and wait until finished
var filterResult = await DoFiltering(...);
DisplayResult(filterResult);
}