C# 调用FFMpegCore时如何从Action访问非静态公共变量
解决方案
你遇到的问题本质是代码笔误+闭包初始化时机不对,不需要修改FFMpegCore的任何签名,按下面步骤改就行:
- 首先修正字段命名错误:C#标识符不允许使用中划线,你定义的
person-int是非法命名,和构造函数里赋值的person_int完全不是同一个变量,先把字段名统一改成下划线格式,同时修正构造函数的参数重名问题:
public class CADEMedia { public string org_int = string.Empty; public string person_int = string.Empty; // 把原来的person-int改成person_int private readonly YourSignalRService _signalR; // 建议通过构造函数注入SignalR实例,不要用全局静态引用 public CADEMedia(string org_int, string person_int, YourSignalRService signalR) { this.org_int = org_int; this.person_int = person_int; _signalR = signalR; }
- 不要把
progressHandler定义成类字段初始化器:字段初始化器的执行顺序早于构造函数内的赋值逻辑,你在初始化器里写的lambda捕获的是未赋值的空字段,当然拿不到正确值。最稳妥的写法是直接在调用转码逻辑的地方就地传入lambda闭包,闭包会自动捕获当前类实例的所有公共/私有字段,多用户并发发起转码时,每个实例的闭包会独立持有自己的org_int、person_int值,完全不会串数据:
// 转码执行的实例方法内直接写 await FFMpegArguments .FromFileInput(inputFile) .OutputToFile(outputFile, true, options => options .WithCustomArgument(customArguments) .WithFastStart()) .NotifyOnProgress(progress => { // 这里可以直接访问当前实例的org_int、person_int,不需要额外传参 _signalR.SendSignalR(org_int, person_int, "message", $"{progress}% Complete"); }, videoDuration) .ProcessAsynchronously();
如果你坚持要把progressHandler抽成类成员复用
不要在字段声明时初始化,把赋值逻辑移到构造函数内即可:
public class CADEMedia { public string org_int = string.Empty; public string person_int = string.Empty; private readonly YourSignalRService _signalR; public Action<double> progressHandler; // 仅声明,不初始化 public CADEMedia(string org_int, string person_int, YourSignalRService signalR) { this.org_int = org_int; this.person_int = person_int; _signalR = signalR; // 构造函数内初始化,此时实例字段已经完成赋值,闭包捕获的值正确 progressHandler = p => { _signalR.SendSignalR(org_int, person_int, "message", $"{p}% Complete"); }; } }
注意:绝对不要把
progressHandler、org_int、person_int定义成static静态字段,静态字段是全局共享的,多用户并发时后启动的转码任务会覆盖前面的字段值,导致进度消息推送给错误的用户。
内容的提问来源于stack exchange,提问作者Velocedge
相关产品推荐
相关产品推荐

