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.
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;
}
}
Related
The output looks something like:
] [ Your input is: ffffffwwqqqwffasfffffffw
>
when you use BACKSPACE which shouldn't be possible to begin with,
why is this happening
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApp7
{
class Program
{
public static string input;
static Program()
{
input = string.Empty;
}
static void Main(string[] args)
{
while (true)
{
ConsoleKeyInfo consoleKeyInfo;
Console.Clear();
Console.Out.Write($"\r\n\t[ Your input is: {input} ]\r\n\r\n\t>");
consoleKeyInfo = Console.ReadKey();
if (consoleKeyInfo.Modifiers == default(ConsoleModifiers))
input += consoleKeyInfo.KeyChar;
Thread.Sleep(250);
}
}
}
}
Backspace is a valid char for ReadKey to process, and when you concatenate a backspace char to the string, it will remove the last character from the string in the output. You can check whether the key that was pressed was a backspace and ignore it.
if (consoleKeyInfo.Modifiers == default(ConsoleModifiers) && consoleKeyInfo.Key != ConsoleKey.Backspace)
input += consoleKeyInfo.KeyChar;
The semaphore means to specify the count how many threads can enter into critical region at a time.
The following code set the count is 5.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static Semaphore semaphore = new Semaphore(5, 5);
static void Main(string[] args)
{
Task.Factory.StartNew(() =>
{
for (int i = 1; i <= 15; ++i)
{
PrintSomething(i);
if (i % 5 == 0)
{
Thread.Sleep(2000);
}
}
});
Console.ReadLine();
}
public static void PrintSomething(int number)
{
semaphore.WaitOne();
Console.WriteLine(number);
semaphore.Release();
}
}
}
Which means each time we can have 5 threads running at any time. The printing result verifies the point.
My question is that I don't see so many threads running. Say 15 threads running, each time only can let 5 threads to be coexisting. There are only two threads.
Am I misunderstood something?
You start one additional thread using Task.Factory.StartNew() and that's it. In that thread you are calling the PrintSomething() method sequentially, so your thread output screenshot is correct.
Change your code as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SempahoreTest1
{
class Program
{
static Semaphore semaphore = new Semaphore(5, 5);
static void Main(string[] args)
{
for (int i = 1; i <= 15; ++i)
{
Task.Factory.StartNew((state) =>
{
int number = (int)state;
PrintSomething(number);
if (i % 5 == 0)
{
Thread.Sleep(2000);
}
}, i);
}
Console.ReadLine();
}
public static void PrintSomething(int number)
{
semaphore.WaitOne();
try
{
Console.WriteLine("Thread: {0}, Number: {1}", Thread.CurrentThread.ManagedThreadId, number);
}
finally
{
semaphore.Release();
}
}
}
}
Update:
A better explanation, how a semaphore works, would be:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SempahoreTest1
{
class Program
{
static Semaphore semaphore = new Semaphore(5, 5);
static Random random = new Random();
static void Main(string[] args)
{
Parallel.For(1, 16, PrintSomething);
Console.ReadLine();
}
public static void PrintSomething(int number)
{
semaphore.WaitOne();
try
{
Console.WriteLine("Thread: {0}, Number: {1}, Access granted", Thread.CurrentThread.ManagedThreadId, number);
// sleep to simulate long running method
Thread.Sleep(random.Next(1000, 5000));
}
finally
{
semaphore.Release();
Console.WriteLine("Thread: {0}, Number: {1}, Semaphore released", Thread.CurrentThread.ManagedThreadId, number);
}
}
}
}
The parallel loop calls PrintSomething() from different threads. On every call the semaphore counter is decreased, until it reaches 0. The next call of PrintSomething() blocks on semaphore.WaitOne(), until the first calls semaphore.Release(), that increments the semaphore counter again. And so on...
The first 5 calls are very fast, because the maximum semaphore count (5) is available. Then, due to the different sleep times, the method call outputs show you, how the semaphore works.
I am thinking that when I start my first thread, it should print "one + n" and lock l,then after this, it should start the second thread and print "two + n".
What actually happens, is that when I run the program I get random results, sometimes printing "one + n", other times printing "two + n"
My understanding of this is obviously flawed - why?
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class locked
{
public long numtochange { get; set; }
public string threadname { get; set; }
}
class Program
{
public static locked l;
static void Main(string[] args)
{
l = new locked();
(new Thread(x => { l.threadname = "one"; Print(l); })).Start();
(new Thread(x => { l.threadname = "two"; Print(l); })).Start();
Console.ReadLine();
}
public static void Print(locked l)
{
lock (l)
{
for (long i = 0; i < 1000; i++)
{
l.numtochange = i;
Console.WriteLine(l.threadname + " " + l.numtochange);
}
}
}
}
}
This part of your code:
l.threadname = "one";
and the corresponding one with = "two" are not locked. Hence they can interleave randomly - sometimes the string "one" ends up in l.threadname and sometimes it is being overwritten by "two". Then, the first thread that manages to get to the lock statement in the Print function does its job and the other one waits.
The simplest fix, if you want them to run sequentially, is to wrap both statements with the lock keyword, like this:
lock (l) { l.threadname = "one"; Print(l); }
(lock is reentrant so there will be no problem with another lock in Print).
However if they always run one after another then there is no point in using threads.
I've been working on a C# console application, and have successfully instituted a palindromic check based on the user inputing an int. I'm now having trouble with the condition involving addition of the user input and the reverse of said input. I want to continue checking for a palindromic number via this addition and then stop execution of the program when one is reached. My program appears to have difficulty saving the state of the reversed number, any help would be much appreciated:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MathPalindromeConsoleApplication
{
class Program
{
static void Main(string[] args)
{
int num, temp, remainder, reverse = 0;
Console.WriteLine("Enter an integer \n");
num = int.Parse(Console.ReadLine());
bool palindromic = true;
temp = num;
while (num > 0)
{
remainder = num % 10;
reverse = reverse * 10 + remainder;
num /= 10;
}
Console.WriteLine("Given a number is = {0}", temp);
Console.WriteLine("Its reverse is = {0}", reverse);
while (palindromic)
{
if (temp == reverse)
{
Console.WriteLine("Number is a palindrome \n");
palindromic = false;
Console.ReadLine();
}
if (temp != reverse)
{
Console.WriteLine("Number is not a palindrome \n");
Console.WriteLine(temp += reverse);
Console.ReadLine();
}
}
}
}
}
I was going to say the same thing as L.B. He put it in a comment, so I'll put it here. Why not use:
bool pal = num.ToString() == new string(num.ToString().Reverse().ToArray());
i just need to be able to loop a console app. what i mean by that is:
program start:
display text
get input
do calculation
display result
display text
get input.
REPEAT PROCESS INFINATE NUMBER OF TIMES UNTIL THE USER EXITS THE APPLICATION.
program end.
i hope that made sense. can anyone please explain how i would go about doing this? thank you :)
Console.WriteLine("bla bla - enter xx to exit");
string line;
while((line = Console.ReadLine()) != "xx")
{
string result = DoSomethingWithThis(line);
Console.WriteLine(result);
}
while(true) {
DisplayText();
GetInput();
DoCalculation();
DisplayResult();
DisplayText();
GetInput();
}
The user can stop the program at any point with CTRL-C.
Is this what you meant?
You could wrap the whole body of your Main method in program.cs in a while loop with a condition that will always be satisfied.
E.g (in pseudo-code)
While (true)
{
Body
}
Kindness,
Dan
Use a While loop
bool userWantsToExit = false;
get input
while(!userWantsToExit)
{
do calc;
display results;
display text;
get input;
if (input == "exit")
userWantsToExit = true;
}
program end;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace InputLoop
{
class Program
{
static long PrintFPSEveryXMilliseconds = 5000;
static double LimitFPSTo = 10.0;
static void Main(string[] args)
{
ConsoleKeyInfo Key = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false);
long TotalFrameCount = 0;
long FrameCount = 0;
double LimitFrameTime = 1000.0 / LimitFPSTo;
do
{
Stopwatch FPSTimer = Stopwatch.StartNew();
while (!Console.KeyAvailable)
{
//Start of Tick
Stopwatch SW = Stopwatch.StartNew();
//The Actual Tick
Tick();
//End of Tick
SW.Stop();
++TotalFrameCount;
++FrameCount;
if (FPSTimer.ElapsedMilliseconds > PrintFPSEveryXMilliseconds)
{
FrameCount = PrintFPS(FrameCount, FPSTimer);
}
if (SW.Elapsed.TotalMilliseconds < LimitFrameTime)
{
Thread.Sleep(Convert.ToInt32(LimitFrameTime - SW.Elapsed.TotalMilliseconds));
}
else
{
Thread.Yield();
}
}
//Print out and reset current FPS
FrameCount = PrintFPS(FrameCount, FPSTimer);
//Read input
Key = Console.ReadKey();
//Process input
ProcessInput(Key);
} while (Key.Key != ConsoleKey.Escape);
}
private static long PrintFPS(long FrameCount, Stopwatch FPSTimer)
{
FPSTimer.Stop();
Console.WriteLine("FPS: {0}", FrameCount / FPSTimer.Elapsed.TotalSeconds);
//Reset frame count and timer
FrameCount = 0;
FPSTimer.Reset();
FPSTimer.Start();
return FrameCount;
}
public static void Tick()
{
Console.Write(".");
}
public static void ProcessInput(ConsoleKeyInfo Key)
{
Console.WriteLine("Pressed {0} Key", Key.KeyChar.ToString());
}
}
}
You can just put a loop around whatever you're doing in your program.