-1

I for some reason am not able to call another method through the timer and use a variable "x" to input a value into that method using the timer so if anyone could please show me how to properly get a input from the user into that ExecMain method it would be greatly appreciated :)

static void Main(string[] args)
    {                   
        // Timer.
        var t = new Timer(TimerCallback, null, 0, 2000);
        // Prevent the app from closing
        Console.ReadLine();
    }
    private static void TimerCallback(Object o)
    {            
        Console.Clear();
        ExecMain(x);  //This is where i want to to add a "int x = Convert.ToInt32(Console.ReadLine());"
    }                 //So i basically want it to execute the "ExecMain" method every 2 seconds with the "x" input
    static void ExecMain(int input)
    {           
        int treeHeight = input, Space, sX;
        Console.WriteLine("Tree:");
        for (int i = 1; i <= treeHeight; i++)   //Height loop
        {
            for (Space = 1; Space <= (treeHeight - i); Space++)  //space loop
                Console.Write(" ");
            for (sX = 1; sX <= i; sX++)         //left x loop with random ornaments
                Console.Write(GetChar(GetRand()));
            for (sX = (i - 1); sX >= 1; sX--)     //right x loop with random ornaments
                Console.Write(GetChar(GetRand()));
            Console.WriteLine();
        }
        for (int k = 1; k <= (treeHeight - 2); k++)
        {
            Console.Write(" ");
        }
        Console.Write("| |");
        Console.WriteLine();
        Console.ReadLine();
    }
kylebotha
  • 25
  • 5
  • Hi @kylebotha, welcome to SO. What does it mean when you say you are "not able to call another method"? Are you seeing an error? Nothing is happening? Have you debugged this? It looks like you are not starting the timer. – JuanR Aug 14 '19 at 17:31
  • @JuanR On line 11 of the code, the "x" is underlined in red, so i cannot pass input through the timer to the ExecMain method. When I run the program, the timer does start. Sorry i`m unsure of most of the terminology used in C# I only started today, so its difficult to explain what my problem is. – kylebotha Aug 14 '19 at 17:34
  • 1
    Your problem is obvious. You are attempting to execute something every two seconds, but want to read a line from the user to use as the parameter. That doesn't make sense. If you read a line, you could technically be waiting forever if the user doesn't type anything. Why do you need it to execute every two seconds? – JuanR Aug 14 '19 at 17:41
  • So if i run the code ExecMain(10); , then it works and inputs the number "10" into the input variable of the ExecMain Method, but i want the user to be able to enter their own variable instead of having the "10" in ExecMain(10); – kylebotha Aug 14 '19 at 17:42
  • I think what you want is the user to enter a value and `ExecMain` to execute, then ask for input again and repeat until the user decides it's time to end the program? – JuanR Aug 14 '19 at 17:43
  • It needs to execute every two seconds because the output that it shows the user is a Christmas tree with ornaments on it and the ornaments need to change position every two seconds as well as color. The ornaments show at random anyways so if i repeat the code every two seconds and clear console then the tree will apear to be have moving and flashing ornaments – kylebotha Aug 14 '19 at 17:45
  • I only want the user to input a value once, which is the height of the tree, then the ExecMain method needs to repeat itself every two seconds to change the position and color of the ornaments – kylebotha Aug 14 '19 at 17:46
  • What you really want is to pass the user-entered value to the `TimerCallback` handler. And in fact, that delegate type already provides a means for doing so. You could have the user enter the value `x` in the `Main()` method, and then pass `x` instead of `null` when you create the `Timer`. Then the `TimerCallback` method can just cast that value, passed in `o`, back to `int x`. But, you can also add an `int x` parameter to `TimerCallback` and pass that via the technique in the marked duplicate. – Peter Duniho Aug 14 '19 at 18:56

2 Answers2

0

One way of solving this is to make the value entered available globally. You then need to fix your sequence so that you read the value, write the tree for the first time, then kick off the timer:

private int _size;

static void Main(string[] args)
{                   
    //Get the value from user first
    _size = Convert.ToInt32(Console.Readline());

    //Execute the first draw
    ExecMain(_size);

    // Start the timer
    var t = new Timer(TimerCallback, null, 0, 2000);

    // Prevent the app from closing
    Console.ReadLine();
}
private static void TimerCallback(Object o)
{            
    Console.Clear();
    ExecMain(_size);  //This is where i want to to add a "int x = Convert.ToInt32(Console.ReadLine());"
}                 

I am not sure how the Console.Readline() to prevent closing and the Console.Clear() from the callback will interact though. It may not do what you think.

JuanR
  • 7,405
  • 1
  • 19
  • 30
-1

If you want to execute a method every 2 seconds and wait for user input you could just put it in a loop, which would eliminate the Timer object, that needs to be created:

using System.Threading

static void Main()
{
   string input = Convert.ToInt32(Console.ReadLine());
   while(true)
   {
      Console.Clear();
      ExecMain(input);
      Thread.Sleep(2000);
   }
}