C# 如何使用';使用';命令正确吗?

C# 如何使用';使用';命令正确吗?,c#,using-statement,C#,Using Statement,我刚刚创建了这个帐户,所以如果我忘记了一些重要信息,请原谅我 我有以下代码,但我怀疑有内存泄漏。代码的目标是从(模拟)摄像机的图像中获取字节,并用这些字节生成EmguCV图像。问题是生成的数组的长度永远不会保持不变。当我生成一个300x300图像时,我希望数组包含90000个入口。但这种情况很少发生。这个数字在不断变化 我曾尝试按照一些教程介绍如何正确使用“using”命令来处理变量,但到目前为止我失败了。据我所知,我正在使用的字节列表似乎没有IDisposable函数。所以这可能是我失败的原因

我刚刚创建了这个帐户,所以如果我忘记了一些重要信息,请原谅我

我有以下代码,但我怀疑有内存泄漏。代码的目标是从(模拟)摄像机的图像中获取字节,并用这些字节生成EmguCV图像。问题是生成的数组的长度永远不会保持不变。当我生成一个300x300图像时,我希望数组包含90000个入口。但这种情况很少发生。这个数字在不断变化

我曾尝试按照一些教程介绍如何正确使用“using”命令来处理变量,但到目前为止我失败了。据我所知,我正在使用的字节列表似乎没有IDisposable函数。所以这可能是我失败的原因:/

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.Structure;

namespace opencv_test
{
    class Program
    {
        static void Main(string[] args)
        {
            Stemmer.Cvb.Image image = new Stemmer.Cvb.Image(300, 300);
            image.Initialize(125);
            List<byte> values = new List<byte>();
            CopyPixelWithValue(image, values);

            byte[] myArray = values.ToArray();

            Emgu.CV.Image<Gray, Byte> test = new Image<Gray, Byte>(300, 300);
            test.Bytes = myArray;
            test.Save("D:/abc.jpg");
        }

        static unsafe void CopyPixelWithValue(Stemmer.Cvb.Image toGetValuesFrom, List<byte> values)
        {
            int width = toGetValuesFrom.Width;
            int height = toGetValuesFrom.Height;
            var toCopyData = toGetValuesFrom.Planes[0].GetLinearAccess();

            byte* toCopyBase = (byte*)toCopyData.BasePtr;
            long toCopyYInc = toCopyData.YInc.ToInt64();
            long toCopyXInc = toCopyData.XInc.ToInt64();

            Parallel.For(0, height, y =>
            {
                var pSrcLine = toCopyBase + y * toCopyYInc;

                for (int x = 0; x < width; x++)
                {
                    var srcVal = *(pSrcLine + x * toCopyXInc);
                    values.Add(srcVal);
                }
            });
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Threading.Tasks;
使用Emgu.CV;
使用Emgu.CV.Structure;
名称空间opencv_测试
{
班级计划
{
静态void Main(字符串[]参数)
{
Stemmer.Cvb.Image=newstemmer.Cvb.Image(300300);
图像初始化(125);
列表值=新列表();
CopyPixelWithValue(图像,值);
字节[]myArray=values.ToArray();
Emgu.CV.Image test=新图像(300300);
test.Bytes=myArray;
test.Save(“D:/abc.jpg”);
}
静态无效CopyPixelWithValue(Stemmer.Cvb.Image toGetValuesFrom,列出值)
{
int width=从.width开始的ToGetValues;
int height=从高度开始的ToGetValues;
var toCopyData=toGetValuesFrom.Planes[0]。GetLinearAccess();
字节*toCopyBase=(字节*)toCopyData.BasePtr;
long toCopyYInc=toCopyData.YInc.ToInt64();
long toCopyXInc=toCopyData.XInc.ToInt64();
平行。对于(0,高度,y=>
{
var pSrline=toCopyBase+y*toCopyYInc;
对于(int x=0;x

如果您能帮助解决此问题,我们将不胜感激

您的问题是,您正在使用并行循环向“值”列表添加值,同时在多个线程中访问同一列表,这是不安全的,并且会损坏数据。将其更改为常规循环,您可能不会有问题。

由于
Parallel.For
中的非同步多线程代码,您正在丢失字节。下面是修复它的尝试

static void Main(string[] args)
{
    Stemmer.Cvb.Image image = new Stemmer.Cvb.Image(300, 300);
    image.Initialize(125);
    byte[] myArray = GetStemmerImageBytes(image);

    Emgu.CV.Image<Gray, Byte> test = new Image<Gray, Byte>(300, 300);
    test.Bytes = myArray;
    test.Save("D:/abc.jpg");
}

static unsafe byte[] GetStemmerImageBytes(Stemmer.Cvb.Image image)
{
    int width = image.Width;
    int height = image.Height;
    var linearAccess = image.Planes[0].GetLinearAccess();

    byte* sourceBase = (byte*)linearAccess.BasePtr;
    long sourceYInc = linearAccess.YInc.ToInt64();
    long sourceXInc = linearAccess.XInc.ToInt64();

    var result = new byte[width * height];
    Parallel.For(0, height, y =>
    {
        var sourceLine = sourceBase + y * sourceYInc;

        for (int x = 0; x < width; x++)
        {
            var srcVal = *(sourceLine + x * sourceXInc);
            result[y * width + x] = srcVal;
        }
    });
    return result;
}
static void Main(字符串[]args)
{
Stemmer.Cvb.Image=newstemmer.Cvb.Image(300300);
图像初始化(125);
byte[]myArray=GetStemberImageBytes(图像);
Emgu.CV.Image test=新图像(300300);
test.Bytes=myArray;
test.Save(“D:/abc.jpg”);
}
静态不安全字节[]GetStemmerImageBytes(Stemmer.Cvb.Image)
{
int-width=image.width;
int height=image.height;
变量linearAccess=image.Planes[0]。GetLinearAccess();
字节*sourceBase=(字节*)linearAccess.BasePtr;
long sourceYInc=linearAccess.YInc.ToInt64();
long sourceXInc=linearAccess.XInc.ToInt64();
var结果=新字节[宽度*高度];
平行。对于(0,高度,y=>
{
var sourceLine=sourceBase+y*sourceYInc;
对于(int x=0;x
数组和列表都不实现IDisposable,因此不支持使用
。这通常不是问题,因为如果不再需要它们,垃圾收集器最终会处理它们。但是,您应该检查Stemmer.Cvb.Image或Emgu.CV.Image是否实现IDisposable。我认为后者确实如此。在这种情况下,它应该
使用(Emgu.CV.Image test=new Image(300300)){test.Bytes=myArray;test.Save(“D:/abc.jpg”);}
。这将至少立即处理您的
测试
,而无需等待GC运行。或者他可以使用一个列表数据结构,允许多线程写入访问。非常感谢!这确实是问题所在,正常循环返回预期结果。我刚刚检查了处理时间,差异非常小,我将保持这种方式。