【问题标题】:Save method calls with parameters in list and execute them将带有参数的方法调用保存在列表中并执行它们
【发布时间】:2013-11-20 13:26:38
【问题描述】:

我对 c# 还很陌生,只是触及了表面。由于我的技能相当有限,我已经达到了我能做的极限。我想用要调用的方法(包括参数)填充一个列表,并每秒或在任何其他时间段内调用这些方法。

我应该如何开始?我听说过代表,但我不确定它们是否是我需要的,或者它们是否适合我的目的。

对不起,如果这是常识。

【问题讨论】:

  • 既然你说你很缺乏经验,可能值得重新考虑你对任何问题的处理方法。你能提供更多的上下文吗?存储要调用的方法列表可能是不必要的,具体取决于它们的作用和调用它们的情况。
  • 特别是如果您想将它们与参数一起存储。为什么不将这些方法的结果存储在列表中?
  • 你可以做的没有限制
  • “要调用的方法列表”听起来像我们所说的“程序”:) 我想知道你的意思是什么类型的列表,以及为什么你认为你需要这样做......跨度>
  • 是您希望每秒调用一个函数,还是该函数每秒更改一次。你怎么知道函数的顺序是什么?它应该循环。对于在特定时间执行方法,您应该查看 Timermsdn.microsoft.com/en-us/library/…

标签: c# list reflection methods


【解决方案1】:

正如 DeeMac 已经说过的,这似乎不是初学者或 C# 可能需要的东西,您最好解释一下为什么您认为需要这样做。但是,要按照您所说的去做,您可以这样做:

    // Here we have the list of actions (things to be done later)
    List<Action> ActionsToPerform;

    // And this will store how far we are through the list
    List<Action>.Enumerator ActionEnumerator;

    // This will allow us to execute a new action after a certain period of time
    Timer ActionTimer;

    public ActionsManager()
    {
        ActionsToPerform = new List<Action>();

        // We can describe actions in this lambda format, 
        // () means the action has no parameters of its own
        // then we put => { //some standard c# code goes here }
        // to describe the action

        // CAUTION: See below

        ActionsToPerform.Add(() => { Function1("Some string"); });
        ActionsToPerform.Add(() => { Function2(3); });

        // Here we create a timer so that every thousand miliseconds we trigger the
        // Elapsed event
        ActionTimer = new Timer(1000.0f);
        ActionTimer.Elapsed += new ElapsedEventHandler(ActionTimer_Elapsed);

        // An enumerator starts at the begining of the list and we can work through
        // the list sequentially
        ActionEnumerator = ActionsToPerform.GetEnumerator();

        // Move to the start of the list
        ActionEnumerator.MoveNext();

    }

    // This will be triggered when the elpased event happens in out timer
    void ActionTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        // First we execute the current action by calling it just like a function
        ActionEnumerator.Current();

        // Then we move the enumerator on to the next list
        bool result = ActionEnumerator.MoveNext();

        // if we got false moving to the next, 
        // we have completed all the actions in the list
        if (!result)
        {
            ActionTimer.Stop();
        }
    }

    // Some dummy functions...
    public void Function1(string s)
    {
        Console.WriteLine(s);
    }

    public void Function2(int x)
    {
        Console.WriteLine("Printing hello {0} times", x);
        for (int i = 0; i < x; ++i)
        {
            Console.WriteLine("hello");
        }
    }

注意: 在这里,这可以按预期工作,因为我们只是传入了一些常量值。但是,如果您不做如此微不足道的事情,事情就会变得棘手。例如考虑一下:

for (int i = 0; i < 10; ++i)
{
    ActionsToPerform.Add(() => { Function2(i); });
}

这根本不会打印出您所期望的,这与closures 有关,这是一个非常不是初学者的话题。

这实际上是您应该认真考虑为什么需要这样做的第一个原因。如您所见,这里有一些复杂的概念通常不是初学者 C#...

【讨论】:

  • 让我试着澄清一下。这是基本设置:我有一个文件,它指定用户要完成的任务。对于每个任务,文件的作者可以包含他想要完成的尽可能多的条件。然后程序读取文件并在某些情况下启动任务。在编程方面,每个条件都实现了,并且应该重复调用以检查所有条件方法是否同时返回true。为此,我想我想在一个列表中注册所有条件调用,然后在每个时间步遍历它们。
  • 所以在文件中你有一个测试列表,这对应于你的操作顺序?我的上述解决方案是否适合?当您阅读文件并将它们映射到相关的测试功能时,您将它们添加到操作列表中吗?
  • 是的,你的问题。我已经在代码库中使用一些变体来测试您的解决方案。在大多数情况下,它的表现都很好,但是我在 Action 上遇到了一些问题,因为它没有返回任何值。目前我正在使用某种 hack 来为每个操作获取布尔值,将它们缓存在一个列表中,如果一个值为 false,则退出。我也在阅读 Func,但还无法理解它们。我应该期待这个乒乓过程会对性能产生重大影响还是使用 Func?
  • 对于退货,您应该能够与 ActionFunc&lt;bool&gt; 进行几乎直接的交换。当您调用当前 Func 时,您可以像往常一样检查退货并停止计时器,如果它失败了。至于性能影响,标准的 SO 答案是对其进行分析:P 显然存在开销,因为它是一个额外的间接层,但在大多数情况下不会引起注意
  • 谢谢。这应该能让我跟上进度,尽管我觉得有必要稍微研究一下 Func。
猜你喜欢
  • 1970-01-01
  • 2015-02-12
  • 2020-03-31
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 2021-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多