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

.NET 8 WinForms中VideoCaptureDevice无法停止的技术问题

.NET 8 WinForms中VideoCaptureDevice无法停止的解决方案

你在.NET 8 Windows Forms项目中使用VideoCaptureDevice时遇到设备无法停止的问题,调用Stop()方法时抛出异常:

System.PlatformNotSupportedException: 'Thread abort is not supported on this platform.'

相关代码如下:

初始化与启停代码:

videoCaptureDevice = new VideoCaptureDevice(filterInfoCollection[cboCamera.SelectedIndex].MonikerString);
videoCaptureDevice.NewFrame += VideoCaptureDevice_NewFrame;

videoCaptureDevice.Start();
videoCaptureDevice.Stop();

NewFrame事件处理代码:

private void VideoCaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
    try
    {
        if (pic.InvokeRequired)
        {
            pic.Invoke(new MethodInvoker(() =>
            {
                pic.Image = (Bitmap)eventArgs.Frame.Clone();
            }));
        }
        else
        {
            pic.Image = (Bitmap)eventArgs.Frame.Clone();
        }
    }
    catch (Exception ex)
    {
    }
}

问题原因

你使用的VideoCaptureDevice(多来自AForge.NET这类旧库)的Stop()方法内部依赖了.NET Framework时代的Thread.Abort()接口,但.NET 5及以上版本(包括.NET 8)已移除对该接口的支持,因此触发PlatformNotSupportedException,导致设备无法正常停止。

解决方案

方案1:替换为兼容.NET 8的摄像头库

旧库对现代.NET支持不足,建议更换为适配性更好的库,比如:

  • OpenCVSharp4:完全支持.NET 8,功能完善,具备成熟的摄像头捕获API
  • Windows.Media.Capture.MediaCapture:Windows平台原生API,适配WinForms场景

以OpenCVSharp4为例,基础使用示例:

  1. 安装NuGet包OpenCvSharp4.Windows
  2. 实现捕获与停止逻辑:
private VideoCapture _capture;
private Timer _frameTimer;

// 启动摄像头
private void StartCamera()
{
    _capture = new VideoCapture(0); // 0为默认摄像头索引
    _frameTimer = new Timer { Interval = 30 }; // 控制帧率间隔
    _frameTimer.Tick += FrameTimer_Tick;
    _frameTimer.Start();
}

// 定时获取帧并更新UI
private void FrameTimer_Tick(object sender, EventArgs e)
{
    using (Mat frame = new Mat())
    {
        _capture.Read(frame);
        if (!frame.Empty())
        {
            using (Bitmap bmp = BitmapConverter.ToBitmap(frame))
            {
                pic.Image = (Bitmap)bmp.Clone();
            }
        }
    }
}

// 停止摄像头
private void StopCamera()
{
    _frameTimer?.Stop();
    _frameTimer?.Dispose();
    _capture?.Release();
    _capture?.Dispose();
    pic.Image = null;
}

方案2:修改现有代码规避Thread.Abort问题

如果必须继续使用原库,可通过以下方式处理:

  1. 停止前取消事件订阅,避免捕获线程阻塞
  2. 设置标志位控制事件处理逻辑,等待线程完成后再停止设备

示例代码:

private bool _isStopping = false;

// 停止逻辑修改
public void StopCamera()
{
    _isStopping = true;
    // 取消事件订阅
    videoCaptureDevice.NewFrame -= VideoCaptureDevice_NewFrame;
    // 短暂等待事件处理线程收尾
    Task.Delay(100).Wait();
    try
    {
        videoCaptureDevice.Stop();
    }
    catch (PlatformNotSupportedException)
    {
        // 忽略异常,手动释放资源
        videoCaptureDevice.Dispose();
        videoCaptureDevice = null;
    }
}

// 修改NewFrame事件处理
private void VideoCaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
    if (_isStopping) return; // 停止时直接退出处理
    try
    {
        if (pic.InvokeRequired)
        {
            pic.Invoke(new MethodInvoker(() =>
            {
                pic.Image = (Bitmap)eventArgs.Frame.Clone();
            }));
        }
        else
        {
            pic.Image = (Bitmap)eventArgs.Frame.Clone();
        }
    }
    catch (Exception ex)
    {
        // 建议添加日志记录,不要空捕获异常
    }
}

额外注意事项

  • 避免空捕获异常,建议添加日志记录以便排查问题
  • 操作Bitmap后需注意资源释放,防止内存泄漏
  • 更新UI控件时,Invoke方式正确,也可尝试BeginInvoke避免阻塞捕获线程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 21:22:09