简体   繁体   English

c#如何从action中访问一个非静态的公共变量

[英]c# how access a non-static public variable from action

I'm using a NuGet package, FFMpegCore, to transcode videos in a Windows Service created with VS 2022. The package calls an Action during the transcoding process that gives status information which I'd like to return to the user using their org and person IDs.我正在使用 NuGet 包 FFMpegCore 对使用 VS 2022 创建的 Windows 服务中的视频进行转码。该包在转码过程中调用一个操作,该操作提供我希望使用他们的组织和人员返回给用户的状态信息身份证。 The problem is that I don't know how to access a non-static variable from the action.问题是我不知道如何从操作中访问非静态变量。 The variables are defined as non-static because multiple users can be transcoding video at the same time:这些变量被定义为非静态的,因为多个用户可以同时对视频进行转码:

public string org_int = "";
public string person-int = "";

They are instantiated when the class is created:它们在创建类时被实例化:

CADEMedia media = new CADEMedia("151", "9655");
...

public class CADEMedia {
    public CADEMedia(string _org_int, string person_int) {
        org_int = _org_int;
        person_int = _person_int;
    }
    ...

The call to the FFMpegCore transcoding function looks like:对 FFMpegCore 转码函数的调用如下所示:

await FFMpegArguments
.FromFileInput(inputFile)
.OutputToFile(outputFile, true, options => options
.WithCustomArgument(customArguments)
.WithFastStart())
.NotifyOnProgress(progressHandler, videoDuration)
.ProcessAsynchronously();

Then the action, progressHandler, looks like this but neither org_int or person_int are accessible here and that's the problem.然后动作,progressHandler,看起来像这样,但 org_int 或 person_int 都不能在这里访问,这就是问题所在。 I need these values to know where to send the progress:我需要这些值来知道将进度发送到哪里:

public Action<double> progressHandler = new Action<double>(p =>
{
    signalR.SendSignalR(org_int, person_int, "message", p + "% Complete");
});

So, the primary question is: How can I access org_int and person_int from the Action?所以,主要问题是:如何从 Action 访问 org_int 和 person_int? I can't change the Action because it's predefined in a 3rd party package that I didn't write.我无法更改 Action,因为它是在我没有编写的第 3 方包中预定义的。

The problem is in the definition of progressHandler .问题出在progressHandler的定义中。

public Action<double> progressHandler = new Action<double>(p =>
{
    signalR.SendSignalR(org_int, person_int, "message", p + "% Complete");
});

Narrowing down to the basics:缩小到基础:

public Action<double> progressHandler = new Action<double>(...);

Here, progressHandler is a field, and new Action<double>(...) is its field initializer .在这里, progressHandler是一个字段,而new Action<double>(...)是它的字段初始化器 A field initializer is executed during instantiation of the containing class ( CADEMedia ).在包含类 ( CADEMedia ) 的实例化期间执行字段初始化程序。 At that point in time, this is not available yet.在那个时间点, this还不可用。 As you already noticed, it is impossible to access org_int and person_int from within the initializer.正如您已经注意到的,不可能从初始化程序中访问org_intperson_int That is because those properties simply do not exist yet.那是因为这些属性根本不存在。 The compiler knows this, and will give an error:编译器知道这一点,并会给出一个错误:

CS0236 CS0236
A field initializer cannot reference the non-static field, method, or property 'CADEMedia.org_int'字段初始值设定项不能引用非静态字段、方法或属性“CADEMedia.org_int”

The solution is simple: replace = with => .解决方案很简单:将=替换为=>

public Action<double> progressHandler => new Action<double>(...);

This completely changes the code being generated.这完全改变了正在生成的代码。 progressHandler is now a property, and new Action<double>(...) is the implementation of its getter. progressHandler现在是一个属性,而new Action<double>(...)是它的 getter 的实现。 The getter is not executed until the property is actually used.在实际使用该属性之前,不会执行 getter。 At which point the containing class has already been properly instantiated and initialized.此时包含的类已经被正确地实例化和初始化。

Specifically:具体来说:

  • A new action is created (as a result of new Action<double>(...) being evaluated) whenever .NotifyOnProgress(progressHandler, videoDuration) is called.每当.NotifyOnProgress(progressHandler, videoDuration)时,都会创建一个新操作(作为评估new Action<double>(...)的结果)。
  • signalR.SendSignalR(org_int, person_int, "message", p + "% Complete") is executed whenever FFMpegCore calls the progress handler;每当 FFMpegCore 调用进度处理程序时,都会执行signalR.SendSignalR(org_int, person_int, "message", p + "% Complete") a (repeated) consequence of .ProcessAsynchronously() being called.调用.ProcessAsynchronously()的(重复)结果。

TL;DR TL;博士

This should work fine:这应该可以正常工作:

public Action<double> progressHandler => new Action<double>(p =>
{
    signalR.SendSignalR(org_int, person_int, "message", p + "% Complete");
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM