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

Windows Forms应用异步视频处理与新窗口创建异常问题

解决方案

1. 核心问题分析

当前代码的主要问题有两点:

  • textBox2_TextChanged事件会随用户每一次输入字符触发,导致大量重复的后台任务堆积,挤占资源造成UI卡顿
  • 后台线程中直接尝试创建UI窗口(如消息框、进度对话框),违反Windows Forms控件只能在UI线程操作的规则,导致窗口无法正常渲染

2. 修复后的代码示例

private CancellationTokenSource _taskCts;

private async void textBox2_TextChanged(object sender, EventArgs e)
{
    // 取消上一次未完成的任务,避免重复执行
    _taskCts?.Cancel();
    _taskCts = new CancellationTokenSource();

    if (listBox1.Items.Count > 0 
        && int.TryParse(textBox2.Text, out int itemvalue) 
        && int.TryParse(textBox1.Text, out int ratio))
    {
        try
        {
            // 延迟500ms执行,等待用户输入完成后再启动任务
            await Task.Delay(500, _taskCts.Token);
            if (_taskCts.Token.IsCancellationRequested) return;

            await Task.Run(() =>
            {
                if (_taskCts.Token.IsCancellationRequested) return;

                // --------------------------
                // 纯后台执行的FFmpeg处理逻辑
                // --------------------------
                var ffmpegProcess = new Process();
                ffmpegProcess.StartInfo.FileName = "ffmpeg.exe";
                // 示例参数:生成指定尺寸的缩略图
                ffmpegProcess.StartInfo.Arguments = $"-i \"{listBox1.SelectedItem.ToString()}\" -vf \"scale={ratio}:{itemvalue}\" -vframes 1 output.jpg";
                ffmpegProcess.StartInfo.UseShellExecute = false;
                ffmpegProcess.StartInfo.CreateNoWindow = true;
                ffmpegProcess.Start();
                ffmpegProcess.WaitForExit();

                // --------------------------
                // 必须回到UI线程执行UI操作
                // --------------------------
                this.Invoke((Action)(() =>
                {
                    MessageBox.Show("视频处理完成!");
                    // 此处可替换为显示进度对话框、更新UI控件等操作
                }));

            }, _taskCts.Token);
        }
        catch (OperationCanceledException)
        {
            // 任务被取消,无需额外处理
        }
        catch (Exception ex)
        {
            // 在UI线程显示错误信息
            this.Invoke((Action)(() =>
            {
                MessageBox.Show($"处理出错:{ex.Message}");
            }));
        }
    }
}

3. 关键修复点说明

  • 任务取消机制:用CancellationTokenSource取消用户输入过程中未完成的任务,避免多个FFmpeg进程同时运行,减少资源占用
  • 输入延迟触发:Task.Delay(500)等待用户输入停顿后再执行任务,避免频繁触发
  • UI线程切换:所有创建窗口、更新控件的操作必须通过Control.Invoke切换回UI线程,确保UI元素能正常渲染
  • FFmpeg进程配置:设置CreateNoWindow = true避免弹出控制台窗口,UseShellExecute = false保证后台静默执行

4. 额外优化建议

  • 处理前禁用输入控件(如textBox2.Enabled = false),完成后再启用,防止用户重复操作
  • 添加进度条控件,通过Invoke实时更新FFmpeg处理进度
  • 重定向FFmpeg的输出日志,捕获处理细节用于调试或展示给用户

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:25:08