You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中调用grabber.Dispose停止相机时出现空引用异常的解决方法

解决C#停止按钮调用Dispose时的NullReferenceException问题

看起来你遇到的是典型的NullReferenceException问题,结合你的代码场景,大概率是grabber实例未正确初始化、或者释放后仍有事件触发访问它导致的。我来帮你梳理下问题根源和解决办法:

核心问题分析

  • grabber生命周期问题:如果grabber是局部变量(比如在CameraCapture方法内部创建),外部停止按钮无法正确访问到它,调用Dispose时自然会触发空引用错误。
  • 事件未及时移除:你给Application.Idle绑定了FrameGrabber事件,但停止时没有移除这个事件,导致后续Idle触发时,FrameGrabber仍尝试访问已释放/置空的grabber。
  • 未做空值检查:无论是停止按钮还是FrameGrabber方法,都没有先判断grabber是否为null就直接操作,这是触发空引用错误的直接原因。

修复后的代码示例

首先,把grabber声明为类的私有字段,确保在整个类的生命周期内可以访问:

// 类级别字段,保存Capture实例
private Capture _grabber;

启动按钮(FDButton)逻辑优化

private void FDButton_Click(object sender, EventArgs e)
{
    // 先清理之前可能存在的资源,避免重复初始化
    if (_grabber != null)
    {
        Application.Idle -= FrameGrabber;
        _grabber.Dispose();
        _grabber = null;
    }

    // 初始化Capture实例,确保CameraCapture把创建的对象赋值给_grabber
    CameraCapture(); 
    if (_grabber != null) // 加一层检查,确保初始化成功
    {
        Application.Idle += FrameGrabber;
        FDButton.Enabled = false;
    }
}

停止按钮逻辑实现

private void StopButton_Click(object sender, EventArgs e)
{
    // 第一步:先移除Idle事件,防止后续触发FrameGrabber访问已释放的对象
    Application.Idle -= FrameGrabber;

    // 第二步:安全释放grabber实例
    if (_grabber != null)
    {
        _grabber.Dispose();
        _grabber = null;
    }

    // 恢复启动按钮状态
    FDButton.Enabled = true;
}

FrameGrabber方法增加空值保护

private void FrameGrabber(object sender, EventArgs e)
{
    // 先检查grabber是否有效,无效则移除事件并返回
    if (_grabber == null)
    {
        Application.Idle -= FrameGrabber;
        return;
    }

    try
    {
        // 抓取当前帧的逻辑,这里假设你用QueryFrame获取帧
        using (var currentFrame = _grabber.QueryFrame())
        {
            if (currentFrame != null)
            {
                // 处理当前帧的逻辑(比如转换为Bitmap显示)
            }
        }
    }
    catch (Exception ex)
    {
        // 捕获异常,避免程序直接崩溃
        Debug.WriteLine($"帧抓取出错:{ex.Message}");
        // 出错后主动清理资源
        Application.Idle -= FrameGrabber;
        _grabber?.Dispose();
        _grabber = null;
        FDButton.Enabled = true;
    }
}

关键注意事项

  • 确保CameraCapture方法正确将创建的Capture实例赋值给类字段_grabber,而不是使用局部变量。
  • 任何时候操作_grabber前都要做null检查,这是避免空引用错误的基础。
  • 释放资源前一定要先移除相关事件,防止事件回调访问已释放的对象。

内容的提问来源于stack exchange,提问作者Munib

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:31:11