C#使用ThreadPool将文件写入硬盘的线程

时间:2014-10-30 13:20:03

标签: c# multithreading threadpool kinect filestream

我使用kinect v2流来显示彩色图像和身体图像。 现在我想保存彩色图像,但如果我在主线程中添加代码,我不会显示任何内容,因为在硬盘上每秒写入30个文件。 所以我认为使用Thread,特别是ThreadPool,但我有框架异常:

ColorCameraSettings 'colorFrame.ColorCameraSettings' ha generato un'eccezione di tipo 'System.ObjectDisposedException'  Microsoft.Kinect.ColorCameraSettings {System.ObjectDisposedException}

这是我的代码:

private void Reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
    {
        var reference = e.FrameReference.AcquireFrame();
        this.StatusText = "NO BODY";

        frameCount++;
        //Console.WriteLine(frameCount);
        bool dataReceived = false;
        //sw.WriteLine("frame nuovo");
        using (ColorFrame frame = reference.ColorFrameReference.AcquireFrame())
        {
            if (frame != null)
            {

                //image.Source = ToBitmap(frame);
                ThreadPool.QueueUserWorkItem(writeColorImage, frame);


            }
        }..............

并写:

 private void writeColorImage(Object frame)
    {
        ColorFrame colorFrame = (ColorFrame)frame;
        var encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(ToBitmap(colorFrame)));
        using (var filestream = new FileStream(filelocation + "image" + frameCount + ".jpg", FileMode.Create))
            encoder.Save(filestream);
    }
    private BitmapSource ToBitmap(ColorFrame frame)
    {
        int width = frame.FrameDescription.Width;
        int height = frame.FrameDescription.Height;
        PixelFormat format = PixelFormats.Bgr32;

        byte[] pixels = new byte[width * height * ((PixelFormats.Bgr32.BitsPerPixel + 7) / 8)];

        if (frame.RawColorImageFormat == ColorImageFormat.Bgra)
        {
            frame.CopyRawFrameDataToArray(pixels);
        }
        else
        {
            frame.CopyConvertedFrameDataToArray(pixels, ColorImageFormat.Bgra);
        }

        int stride = width * format.BitsPerPixel / 8;

        return BitmapSource.Create(width, height, 96, 96, format, null, pixels, stride);
    }

如何在硬盘上写这个图像?谢谢

2 个答案:

答案 0 :(得分:1)

using语句在你的frame变量上调用Dispose;但是,运行保存到磁盘的线程仍在使用对它的引用。这就是你获得例外的原因。更改此代码:

    using (ColorFrame frame = reference.ColorFrameReference.AcquireFrame())
    {
        if (frame != null)
        {
            //image.Source = ToBitmap(frame);
            ThreadPool.QueueUserWorkItem(writeColorImage, frame);
        }
    }

到此:

    var frame = reference.ColorFrameReference.AcquireFrame();
    if (frame != null)
    {
        //image.Source = ToBitmap(frame);
        ThreadPool.QueueUserWorkItem(writeColorImage, frame);
    }

然后在writeColorImage中调用Frame上的Dispose();像这样改变方法:

    private void writeColorImage(Object frame)
    {
        var colorFrame = (ColorFrame) frame;
        var encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(ToBitmap(colorFrame)));
        using (var filestream = new FileStream(filelocation + "image" + frameCount + ".jpg", FileMode.Create))
        {
            encoder.Save(filestream);
        }
        colorFrame.Dispose();
    }

答案 1 :(得分:1)

您正在线程池上启动作业后立即处理框架。你应该在工作结束时处理它。

在事件处理程序Reader_MultiSourceFrameArrived中删除使用,然后:

 private void writeColorImage(Object frame)
    {
        using (ColorFrame colorFrame = (ColorFrame)frame)
        {
            var encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(ToBitmap(colorFrame)));
            using (var filestream = new FileStream(filelocation + "image" + frameCount + ".jpg", FileMode.Create))
                encoder.Save(filestream);
        }
    }