C#增加相机图像处理的内存

C#增加相机图像处理的内存,c#,thread-safety,C#,Thread Safety,我有一个增加记忆力的问题。我有一张来自照相机的图像。图像由具有非托管代码的函数处理。如果找不到预期的模式,则此函数需要很长时间(几秒钟)。如果可以找到模式,它会很快返回结果(有些毫秒) 我尝试在一个新的线程中启动后处理,并在200毫秒后中止它。到目前为止,这是可行的。现在我的问题是,我的记忆力在增长。可能using子句没有按预期工作,图像保存在内存中 private void ImageWorker() { while (_imageWorkerRunning) {

我有一个增加记忆力的问题。我有一张来自照相机的图像。图像由具有非托管代码的函数处理。如果找不到预期的模式,则此函数需要很长时间(几秒钟)。如果可以找到模式,它会很快返回结果(有些毫秒)

我尝试在一个新的
线程中启动后处理
,并在200毫秒后中止它。到目前为止,这是可行的。现在我的问题是,我的记忆力在增长。可能
using
子句没有按预期工作,图像保存在内存中

private void ImageWorker()
{
    while (_imageWorkerRunning)
    {
        try
        {
            using (var img = CameraHelper.GetImage())
            {
                var waiter = new ManualResetEvent(false);
                ProcessResult result = null;
                var thd = new Thread(() => {
                    result = UnManagedImageProcessor.Process(img);
                    waiter.Set();
                });
                thd.Start();
                waiter.WaitOne(200);
                if (thd.ThreadState == ThreadState.Running || result == null)
                {
                    thd.Abort();
                    while (thd.ThreadState != ThreadState.Aborted) new ManualResetEvent(false).WaitOne(10);
                }

                Application.Current.Dispatcher.Invoke(() => DisplayImage = img);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
    }
}
GC
在中止的线程上工作正常吗?我想这可能是我的问题

解决方案:

我将代码更改为以下内容。现在我有两个并行任务。首先是获取图像并检查处理是否可用

如果是,图像将提供给此
ImageProcessing
任务。仅在
Success
上显示图像(这样处理速度很快,每个图片都可以处理)

如果处理未成功,则需要一些时间,并且图像仅显示为实时图像(由
ImageWorker


谢谢你的帮助。

我建议你使用

要显示可以使用锁定器的图像,每次用户界面空闲时,锁定对象,获取最后一个图像并处理上一个图像。此外,每次处理图像时,您都会锁定对象并将var设置为最后一个

显示逻辑:

readonly object lastProcessdImageLocker = new object();
Bitmap lastProcessdImage;

//Every time a image process is done:
lock(lastProcessdImageLocker)
    lastProcessdImage = imageJustProcessed;

//Every time the UI thread is idle
lock(lastProcessdImageLocker)
    myPictureboxImage = lastProcessdImage;
//Here you should also dispose the previus myPictureboxImage so you prevent your memory usage to grow fast!

使用BlockingCollection消费(处理)相机图像的示例代码:

BlockingCollection<Bitmap> cameraImages = new BlockingCollection<Bitmap>();

如果您的cameraImages计数增长过快(内存不足),则需要缩短处理时间或停止相机一段时间。

您可能希望使用
water.WaitOne(200)
的结果,而不是检查线程状态和结果变量。如果WaitOne超时,则不应触摸结果。(跨线程访问)DisplayImage=img做什么?它是一个具有集合逻辑的属性吗?我猜你正在泄漏GDI资源。但是这里没有足够的代码来说明。例如,正如Jeroen所问,DisplayImage做什么?或非托管DimageProcessor。进程?中止线程是错误的。若方法正在分配一些内存,而您中止了它,该怎么办?当然,它不会被发布=问题。相反,您可以让线程完成其工作,但限制允许在后台继续工作的线程数。或者只是等待一个,但异步填充图像。至于同步
Monitor。输入
/
Leave
is。另外,您应该在threadmethod中添加一个
try/catch
。看起来很棒。我试试这个。明天(当我再次工作时)我会给出反馈!谢谢你的回答。这帮助我找到了一个单独处理循环的解决方案。我很高兴能帮助您。您使用了BlockingCollection?我更新了我的问题并添加了我的解决方案(如您所见)。我只是采用了独立图像处理循环的方法。
BlockingCollection<Bitmap> cameraImages = new BlockingCollection<Bitmap>();
void StartProcess()
{
    if (processImageThread== null || !processImageThread.IsAlive)
    {
        processImageThread= new Thread(ProcessLoop);
        processImageThread.Name = "ProcessLoop";
        processImageThread.IsBackground = true;
        processImageThread.Start();
        Console.TraceInformation("ProcessLoop started");
    }
}
private void ProcessLoop()
{
    try
    {
        foreach (img in cameraImages.GetConsumingEnumerable(CancelProcessing.Token))
        {
            // Do your stuff               
        }
    }
    catch (OperationCanceledException)
    {
        Console.WriteLine("ProcessLoop OperationCanceledException.");
    }
    finally
    {

    }
}