C#如何从操作中访问非静态公共变量

发布于 2025-02-06 17:18:03 字数 1148 浏览 9 评论 0原文

我正在使用Nuget软件包FFMPEGCORE来在使用VS 2022创建的Windows服务中进行转码视频。该软件包在转码过程中调用操作,该操作在转码过程中提供了我希望使用其组织和人员返回用户的状态信息IDS。问题是我不知道如何从操作中访问非静态变量。变量被定义为非静态的,因为多个用户可以同时转码视频:

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

创建类时它们是实例化的:

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;
    }
    ...

呼叫FFMPEGCORE转码函数看起来像:

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

然后,Action,ProgressHandler,看起来都不是这样,但也不是这样org_int或person_int可以在这里访问,这就是问题所在。我需要这些值才能知道在哪里发送进度:

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

那么,主要问题是:如何从操作中访问org_int和person_int?我无法更改操作,因为它是在我没有编写的第三方软件包中预定的。

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. 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:

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. 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? I can't change the Action because it's predefined in a 3rd party package that I didn't write.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

揽清风入怀 2025-02-13 17:18:04

问题在于progressHandler的定义。

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

缩小到基础知识:

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

progressHandler是一个字段,新操作&lt; double&gt;(...)是其字段初始化器
在包含类(cademedia)的实例化期间执行字段初始化器。
在那个时间点,尚不可用。
正如您已经注意到的那样,从初始化器中访问org_intperson_int
那是因为这些属性根本不存在。
编译器知道这一点,并会出现一个错误:

CS0236
字段初始化器不能引用非静态字段,方法或属性'cademedia.org_int'

解决方案很简单:替换=,用=&gt;

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

这完全更改了要生成的代码。
progressHandler现在是属性,新操作&lt; double&gt;(...)是其Getter的实现。
直到实际使用该属性之前,getter才能执行。
在这一点上,包含类已经正确实例化和初始化。

具体来说:

  • 每当.notify> .notifyOnprogress(progressHandler,videeDuroration)时,就会创建一个新的动作(由于新操作&lt; double&gt;(...)被评估。
  • signalr.sendSignalr(org_int,person_int,“ message”,p +“%complete”)每当ffmpegcore调用progress handler时,都会执行; <代码>的(重复)后果。

TL; DR

THIN应该可以正常工作:

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

The problem is in the definition of 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.
A field initializer is executed during instantiation of the containing class (CADEMedia).
At that point in time, this is not available yet.
As you already noticed, it is impossible to access org_int and person_int from within the initializer.
That is because those properties simply do not exist yet.
The compiler knows this, and will give an error:

CS0236
A field initializer cannot reference the non-static field, method, or property '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.
The getter is not executed until the property is actually used.
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.
  • signalR.SendSignalR(org_int, person_int, "message", p + "% Complete") is executed whenever FFMpegCore calls the progress handler; a (repeated) consequence of .ProcessAsynchronously() being called.

TL;DR

This should work fine:

public Action<double> progressHandler => new Action<double>(p =>
{
    signalR.SendSignalR(org_int, person_int, "message", p + "% Complete");
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文