Disable user input until thread.sleep is finished - c#

So i am a beginner programmer.
I am in my second year of learning how to program.
So I am wondering if there is a easy way to wait for the Thread.Sleep to finish in c# console application. Because when i have a thread.sleep and a console.readkey behind that.
The console.ReadKey will execute.
Could someone please explain to me how to do this.
And why this is happening if you feel like it.

Okay so this only happens when i used some other method.
if i were to do this
Thread.Sleep(); //sleep 100 seconds
Console.Read();
nothing happend when i pressed a button.
however using a diffrent method
static void Main(string[] args)
{
IntervalMessage("this is a test");
Console.ReadKey();
}
public static void IntervalMessage(string message)
{
for (int i = 0; i < message.Length; i++)
{
if (i == message.Length - 1)
{
Console.Write(message[i]);
System.Threading.Thread.Sleep(120);
}
else
{
Console.Write(message[i]);
System.Threading.Thread.Sleep(110);
}
}
Console.ResetColor();
}
it will be able to have take input while sleeping.
Thanks for trying to help. figured it out myself.

Related

How to use System.Timers.Timer properly inside a class

I'm trying to learn how to use Timers and I'm having troubles with the elapsed event.
What I have is a class where I check some messages from a databatch. But now I want to make a timer where every x period of time check that messages.
I made this code:
public class Program
{
static void Main(string[] args)
{
Message m = new Message();
m.init();
}
}
public class Messages{
private System.Timers.Timer tt;
public void init()
{
tt = new(_conf.Period);
tt.Elapsed += new System.Timers.ElapsedEventHandler(TimerElapsed);
tt.Start();
Console.ReadLine();
}
private void TimerElapsed(object? sender, ElapsedEventArgs e)
{
//Console.WriteLine for test it works
Console.WriteLine(DateTime.UtcNow);
//check my messages
}
}
This doesn't work because it never goes inside TimerElapsed. What am I doing wrong?
Thank you
EDIT: even as a field timer doesn't goes inside elapsed event.
EDIT2: well, I found my problem. I was testing the TimerElapsed with a Console.WriteLine(DateTime.UtcNow) inside of it and it only works if i put after all the code on Init a Console.ReadLine(); Ill edit my code again to show it. I don't understad why I need this readLine so if someone could explain to me would be great.
If you don't like the ReadLine() approach, you can use a polling loop like this instead:
public static void Main (string[] args) {
Messages m = new Messages();
m.init();
ConsoleKeyInfo cki;
do {
while (!Console.KeyAvailable) {
System.Threading.Thread.Sleep(50);
}
cki = Console.ReadKey(true);
} while (cki.Key != ConsoleKey.Escape);
}
This will keep the app alive until the user hits the Escape key.
You should see the timestamps printing at whatever interval you specified.

How to allow a thread to finish while another thread is sleeping

I am writing a C# Console Application that handles multiple threads, but for some of the threads I have to wait for some time while other threads are waiting to finish sleep time for the thread which is in sleep. So how can I achieve parallel programming when one thread is sleeping, but other threads should work at the same time?
A solution that I tried is below. The output which I'm expecting is as i == 1 is in sleep mode for 1 min till the time other two i == 2 and i == 3 should get printed in the meantime.
static void Main(string[] args)
{
for (int i = 0; i < 10; i++) {
if (i == 1) {
Console.WriteLine("1");
System.Threading.Thread.Sleep(60000);
}
else if (i == 2) {
Console.WriteLine("2");
}
else if (i == 3) {
Console.WriteLine("3");
}
}
}
OUTPUT
2
3
(after one minute) 1
Here is your simple solution:
static void Main(string[] args)
{
Task task = null;
for (int i = 0; i < 10; i++)
{
if (i == 1)
{
task = Task.Run(() => {
Thread.Sleep(60000);
Console.WriteLine("1");
}
);
}
else if (i == 2)
{
Console.WriteLine("2");
}
else if (i == 3)
{
Console.WriteLine("3");
}
}
task.Wait();
}
But I'm pretty sure that you need much more understanding, how the threads work. Good luck :)
As mjwills pointed out, you only have one thread here.
When you start an application, this will create one thread, usually it is called the main thread. To avoid your program from freezing you tend to try not to Thread.Sleep() in the main thread.
That being said when you want to create a new task which is similar to a thread you can process this way :
static void Main(string[] args)
{
Task yourTask = Task.Run( () => {
// Do Something, like your sleep.
});
yourTask.Wait();
}
If you want your task to run synchronously (for exemple you need to wait that something ends before you can continue your program), I suggest you see the RunSynchronously() method from the Task Class in the link above. If you want for it to run asynchronously (for example you don't need to wait that something ends before you can continue your program), you can check this link.
Hope this helps.
While I know this will downvoted, I can't help but point out the simplest solution to your problem is likely:
static void Main(string[] args)
{
Console.WriteLine("2");
Console.WriteLine("3");
System.Threading.Thread.Sleep(60000);
Console.WriteLine("1");
}
It gives the exact output you are aiming for. It is simple, and easy to read and understand. It doesn't use a loop or an extra thread - but the code in your question doesn't need either of those things.

C# Method that restarts Main()

I have a C# method, if a condition is not met I want to re-run the Main() method.
There are a few posts saying use loops to do this. GoTo would also work - but don't use it. Or restart the application.
No one has given a clear newbie-level explanation about the loops.
C# example:
public static void Method3(int userChoice){
if(userChoice == 1){
Console.WriteLine("do this");
}
else{
Main(); // How to run the main program again from the start ?
}
}
public static void Main(string[] args)
{
Method1();
int userChoice = Method2();
Method3(userChoice); // I want Method3 to go back to Method1() if the else statement is met.
}
In python this is real easy - you just call Main() from the function.
You can have Method3() return a bool so the Main() method knows whether to try again.
public static bool Method3(int userChoice)
{
if (userChoice == 1)
{
Console.WriteLine("do this");
return false;
}
return true;
}
public static void Main(string[] args)
{
bool tryAgain;
do
{
Method1();
int userChoice = Method2();
tryAgain = Method3(userChoice);
} while (tryAgain);
}
Simply calling Main() again instead of looping is another approach, but has some disadvantages.
You'll have to come up with the args argument somehow. Maybe it's just an empty array in your case.
It's a recursive call and affects the stack trace. After so many recursive calls, your application will crash.
It decreases maintainability. You'll have to remember in the future if you want to add anything to the top of the Main() method that you're calling it from somewhere. It lends itself to the introduction of potentially hard-to-diagnose bugs. Using the loop approach encapsulates the behavior. From just looking at Main(), it's obvious that Method3() might cause another loop.
First of all, yes, you can call Main. Please note that in your example you are missing the args parameters (which would have the command line arguments). Besides that, also know that Main returns, and then execution continues after where you called it. Also, you would very likely end up with a stack overflow. If I recall correctly modern versions of the JIT can optimize tail recursion, yet I do not believe they do for this particular case.
About that newbie-level explanation of a loop... this is an infinite loop, it will run forever:
while(true)
{
// ...
}
You can exit the loop with break
while(true)
{
// ...
if (something)
{
break;
}
// ...
}
Or you can change that true for a conditional:
while(!something)
{
// ...
}
The idea would be to wrap Main in a loop, so that it would continue to run until a condition is met. You could have another method and call it in the loop, for example:
public static bool Execute()
{
if (something)
{
// do whatever
return true;
}
return false;
}
public static void Main(string[] args)
{
while (!Execute())
{
// Empty
}
}
There are, of course, other kinds of loops aside from the while loop, they are the do...while loop, for loop, and foreach loop.
Goto would work? Arguably. The idea is that you can use goto to control the flow of execution to back in the method. That is:
label:
// ...
goto label;
The above code is an infinite loop. You can, of course, introduce a condition:
label:
// ...
if (!something)
{
goto label;
}
// ...
The while can do – sometimes with the help of a variable – whatever you can do with goto, and it is usually easier to read and less error prone.
Restarting the process is a bit more tricky, you need to use Process.Start to run your own executable. See What is the best way to get the executing exe's path in .NET?.
So it's not really hard to do but you can just use a while loop.
C#:
public static void Main(string[] args)
{
while(true)
{
Method1();
int userChoice = Method2();
Method3(userChoice);
}
}
That would give you what you want and if you want to exit you just put
break;

is AutoResetEvent waitOne() function what I am looking for?

I am new on this forum but I have always checked it out and I appreciate it very much.
I must say in the beginning that I am not a very skilled or knowledgable software programmer and for the past days I am stuck on a problem. I have a barcode reader on my COM1 port. I connect, I write "TRIGGER", it returns with(hopefully) "OK", when I have the OK, then I send a "READ", and it comes back with a big line with some fields. So here is right now how my code looks like; (the code is mainly like this. I didn`t write it all but the serialPort and waitHandle stuff is like below)
in SerialPortExample class,
public AutoResetEvent waitHandle = new AutoResetEvent(false);
public string Read()
{
for (int i=0; i<1000; i++) {
this._serialPort.Write("TRIGGER" + Convert.ToChar(0));
waitHandle.WaitOne();
// a couple lines of stuff
this._serialPort.Write("GETSTRINGRESULTS" + Convert.ToChar(0));
waitHandle.WaitOne();
if (OBarcode.ReadStatus == ReadStatus.SUCCESS) {
return OBarcode.BarcodeString;
}
}
return "";
}
this is raised when some answer from serialPort
void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try {
string value = _serialPort.ReadExisting();
...
// stuff
waitHandle.Set();
} catch(Exception ex) {
// stuff
}
}
in the form with behind a button click, I open the connection, do the Read(), Close() the connection and so on. I have seen this AutoResetEvent online and decided to use. When I click the button for the first time, everything runs smooth, but, if I click the button again. which reoopens the closed connection and does the read again, this time the WaitOne() doesn`t wait.
I would appreciate very much appreciate your help. How should I normally handle this? I am doing something seriously wrong.

C# Threading program | Regarding thread.join

In the below program why the t.join functionality is not working. It will continue to type character O on the screen even when i have specified it to wait for the another thread to complete.
class Program
{
bool done;
static void Main(string[] args)
{
Thread t = new Thread(() => Go('U'));
for (int i = 0; i < 1000; i++)
{
Console.Write('O');
Thread.Sleep(500);
}
t.Start();
t.Join();
Console.WriteLine("Thread t has ended!");
Console.Read();
}
static void Go(char p)
{
for (int i = 0; i < 1000; i++)
{
Console.Write(p);
Thread.Sleep(500);
}
}
}
You never started the second thread - you're printing out Os, but you only start the second thread after you're done with that (in about eight minutes).
Move the t.Start(); before the loop, and it should work the way you expect it to work.
Don't guess around with multi-threading - it's incredibly easy to get subtly wrong. Learn what a thread is, what does Join do, and how to use multiple threads safely. Otherwise, you'll have a lot of fun debugging issues that are near impossible to reproduce and fix :)

Categories

Resources