简体   繁体   中英

Disposing object in async event C# WPF

Im usign Kinect SDK in a WPF application and im listenting the DepthFrameReady event to make some operations. In order to avoid UI blocks i made the event async and im "awaiting" the function that made the data operations.

Rigth now in the output window in visual studio im getting the message:

WARNING: An imageFrame instance was not disposed

I tried many things to dispose the DepthImageFrame (put logic inside using block, callback when async function ends, etc...) but after first call it is sending null, so...

Which is the rigth way to dispose the object in async/await events? .


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;
}

My impression here is that you are mixing responsibilities. To make things clear, every object should have an owner - the one who instantiates it and disposes it. In your solution, those are two entities - the event handler which constructs the DataDepthImageFrame , and the task which does the work.

In my opinion, the function which starts the task shouldn't construct the image frame, but instead prepare a factory function for it. That would allow the task to both instantiate and dispose the object. In that way, the task would be entirely responsible for that object.

Of course, if you plan to capture the factory in the closure, then you don't even need it - you can capture event arguments e and use them in the task directly.

private async void KinectSensorFound_DepthFrameReady(
    object sender, DepthImageFrameReadyEventArgs e)
{
   await Task.Run(
     () => 
     {
       using (DepthImageFrame DataDepthImageFrame = e.OpenDepthImageFrame())
       {
           UpdateUserDepthInfo(DataDepthImageFrame)
       }
   });
}

I cannot reproduce your scenario, but I believe that the image frame from the event arguments will survive to be opened in another thread when the task starts running.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM