Home > Enterprise >  Program that writes numbers until I write a string to stop it
Program that writes numbers until I write a string to stop it

Time:04-27

I am required to write a program that prints out numbers until I write in the console window a simple string "stop". The numbers are supposed to go on infinitely until the condition is met.

I tried:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;


namespace ConsoleApp3

{

    internal class Program

    {


        static void Main(string[] args)
        {
            for (int i = 0; i < 1000000000;)
            {
                Console.WriteLine(i);
                string a = Console.ReadLine();
                if (a == "stop")
                {
                    break;
                }
                i  ;
            }
        }
    }
}

But, there is a delay waiting for my input every time, it's not constant.

CodePudding user response:

You are asking for a non blocking console read. THats not simple.

One way is to peek to see if a key is available to read

int number = 0;
while (true)
{
   Console.WriteLine(number);
   number  ;
   if (Console.KeyAvailable)
   {
       var s = Console.ReadLine();
       if (s == "stop")
          break;
   }
}

CodePudding user response:

To interrupt the Console.Readline call I used a solution by Gérald Barré (https://www.meziantou.net/cancelling-console-read.htm). We need to import a method CancelIoEx to cancel the ReadLine request. Using GetStdHandle as a way to identify what input request we want to cancel.

If a key is pressed the program will send an input request, but the program will continue as normal if the user waits too long.

Edit: Included further explaination as Lance mentioned I should've done.

using System.Runtime.InteropServices;

const int STD_INPUT_HANDLE = -10;

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CancelIoEx(IntPtr handle, IntPtr lpOverlapped);

int val = 0;
bool run = true;
bool typing = false;
while(run)
{
  if(!typing)
  {
    Console.WriteLine(val);
    val  ;
    if(Console.KeyAvailable)
    {
      typing = true;
    }
  }
  else
  {
    var read = false;
    Task.Delay(10000).ContinueWith(x =>
    {
      if(!read)
      {
        var handle = GetStdHandle(STD_INPUT_HANDLE);
        CancelIoEx(handle, IntPtr.Zero);
      }
    });

    try
    {
      Console.WriteLine("Interrupting output for user input (10 seconds given)");
      string s = Console.ReadLine();
      if(s == "stop")
        run = false;
      else
        typing = false;
    }
    catch(OperationCanceledException)
    {
      Console.WriteLine("Timeout, press any key to pause again.");
      typing = false;
    }
  }
}
  •  Tags:  
  • c#
  • Related