How to check thread is sleeping in x second c# - c#

I write application need check if time to checkLogin() sleep over > 30 seconds.
Then, it will break this while loop and continues the program.
My code like this:
while(!Account.checkLogin())
{
Thread.Sleep(1000);
}
How to check like:
while(!Account.checkLogin())
{
Thread.Sleep(1000);
if(Thread.Sleep like 30000)
continues;
}

If I understood the question correctly, you could sum up the iterations and and use them in the termination condition as follows.
int MAX_ITERATIONS = 30;
int NumOfIterations = 0;
while(!Account.checkLogin() && NumOfIterations < MAX_ITERATIONS)
{
Thread.Sleep(1000);
NumOfIterations++;
}

You can just sleep for 30 seconds:
Thread.Sleep(30000);
However that's holding up the thread and stops you doing anything inbetween. I prefer to use a TimeSpan, for example:
DateTime started = DateTime.UtcNow;
while (!Account.checkLogin())
{
TimeSpan ts = DateTime.UtcNow - started;
if (ts.TotalSeconds >= 30)
break;
Thread.Sleep(1000);
}

Related

Launch a program every 12 hours

I want to launch a method in a program every 12 hours.
What do I have to do ?
Do I have to use a Timer to doing this ?
I have this code :
aTimer = new System.Timers.Timer(1000); //One second, (use less to add precision, use more to consume less processor time
int lastHour = DateTime.Now.Hour;
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Start();
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
if(lastHour < DateTime.Now.Hour || (lastHour == 23 && DateTime.Now.Hour == 0))
{
lastHour = DateTime.Now.Hour;
YourImportantMethod(); // Call The method with your important staff..
}
}
Can I adapt it to launch my program every 12 hours ?
A simple solution with async/await:
private static async void RepeatedAction()
{
TimeSpan delay = TimeSpan.FromHours(12);
while (true)
{
await Task.Delay(delay);
YourImportantMethod();
}
}
Use System.Threading.Timer
var start = TimeSpan.Zero;
var period = TimeSpan.FromHours(12);
var timer = new System.Threading.Timer((e) =>
{
YourImportantMethod();
}, null, start, period);
You can use Cron Jobs for this situation
Here is url check and implement. In corn job you can set when your program run

Execute scheduled Task only once

I was trying to Code some simple scheduled Task, which should be executed every full minute (aka when seconds are at 0) but somehow it got messed up. Instead of only doing its job once, it does it over and over as long as the seconds are at 0.
I tried to prevent that by using a bool indicator, but that didnt work.
Hier is my Code example:
static void Main()
{
bool now = true;
while (true)
{
if (DateTime.Now.Second == 0 && now == true)
{
Console.WriteLine("now is: " + DateTime.Now);
now = false;
}
else
{
now = true;
}
}
}
I would prefer to not use sleeps or delays and would like to schedule it by actual time.
Is there an easy way to solve this?
Keep track of your current time and your next run time by changing your code to something like
static void Main(string[] args)
{
var now = DateTime.Now;
var nextRunTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0).AddMinutes(1);
while (true)
{
var currentTime = DateTime.Now;
if (currentTime >= nextRunTime)
{
Console.WriteLine(currentTime);
nextRunTime = nextRunTime.AddMinutes(1);
}
}
}

how to make an order in right time C#

first sorry for my bad English
i want to make an order in my program when it come 12:00 AM in my PC
i try with this code
string Time = "00:00 AM";
while (true)
{
if (Time == DateTime.UtcNow.ToString("hh:mm tt"))
{
Console.ForegroundColor = ConsoleColor.Blue;
// Update Days -1 Where Service = 1
sqlCon.exec("update HelperSystem set Days = Days-1 where Service=1 and Days != 0");
Meldung("Updated HelperSystem Table Days -1");
// Update Service = 0 Where Days = 0
sqlCon.exec("update HelperSystem set Service = 0 where Days = 0");
Meldung("Updated HelperSystem Table Service = 0 Where Days = 0");
// Update Days -1 Where Service = 1
sqlCon.exec("update AutoEvent set Days = Days-1 where Service=1 and Days != 0");
Meldung("Updated AutoEvent Table Days -1");
// Update Service = 0 Where Days = 0
sqlCon.exec("update AutoEvent set Service = 0 where Days = 0");
Meldung("Updated AutoEvent Table Service = 0 Where Days = 0");
Console.ResetColor();
Thread.Sleep(120000);
}
Thread.Sleep(1);
}
and when i try with breakpoint return value 12:00 AM but didn't do anything
If you're trying to match times using a formatted string then you should ensure you're comparing against the same format. You should do something like this:
string timeFormat = "hh:mm tt";
string Time = (new DateTime(1970, 1, 1, 0, 0, 0)).ToString(timeFormat); //12:00 AM
while (true)
{
if (Time == DateTime.UtcNow.ToString(timeFormat))
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("Run.");
Console.ResetColor();
Thread.Sleep(120000);
}
Thread.Sleep(1);
}
However, this approach isn't great. You really have nothing ensuring that the process will actually execute at the right time of day to ensure equality works. In this case you'd be very unlucky as it only has to run once in the 60 seconds that the time text is correct, but there is no guarantee. You really should compare against a specific time.
This is better:
DateTime Time = DateTime.UtcNow.AddDays(1.0).Date;
while (true)
{
if (DateTime.UtcNow > Time)
{
Time = DateTime.UtcNow.AddDays(1.0).Date;
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("Run.");
Console.ResetColor();
}
Thread.Sleep(1);
}
There's no need for the messy Thread.Sleep(120000); in this code.
However, you still have the Thread.Sleep(1); call which is bad.
I'd suggest using a library that has been designed for this kind of thing. Try Microsoft's Reactive Framework (NuGet "System.Reactive") and then you can do this:
IDisposable subscription =
Observable
.Timer(DateTimeOffset.UtcNow.AddDays(1.0).Date, TimeSpan.FromDays(1.0))
.Subscribe(x =>
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("Run.");
Console.ResetColor();
});
When you're closing down your app just call subscription.Dispose(); and it'll cleanly stop.
Change string Time = "4:30 AM"; to "04:30 AM"
public static void Main()
{
string Time = "4:30 AM";
while (true)
{
Console.WriteLine("{0}",DateTime.UtcNow.ToString("hh:mm tt"));
// Prints 04:30 AM - so that is why it does not match 4:30 AM
if (Time == DateTime.UtcNow.ToString("hh:mm tt"))
{
Console.ForegroundColor = ConsoleColor.Blue;
// Update Days -1 Where Service = 1
Console.WriteLine("I am In");
Console.ResetColor();
}
Thread.Sleep(1000);
}
}

Timer to exact time by seconds

I'm trying to run an infinite loop in parallel with the other code, that is executed once a specific time acheived by SECOND.
In the below code I'm trying to touch the exact midnight time, that is: 00 hh: 00 mm: 00 sec
using System; // for Date/Time
using System.Threading.Tasks; // for Parallel
public class Program
{
public static void Main(string[] args)
{
Parallel.Invoke(
() =>
{
Console.WriteLine("Begin first task...");
}, // close first Action
async () =>
{
Console.WriteLine("Begin second task...");
var midNight = "00:00:00";
while (true)
{
TimeSpan duration = DateTime.Parse(midNight).Subtract(DateTime.Now);
Console.WriteLine("looping at: {0:00} Days, {1:00} Hours, {2:00} Minutes, {3:00} Seconds, {4:00} Milliseconds",
duration.Days, duration.Hours, duration.Minutes, duration.Seconds, duration.Milliseconds);
if(duration.Days >= 1)
await Task.Delay(8640000);
else if(duration.Hours >= 1)
await Task.Delay(360000);
else if(duration.Minutes >= 1)
await Task.Delay(60000);
else
await Task.Delay(1000);
if(duration == TimeSpan.Zero) {
Console.WriteLine("It is time... midnight is {0}", DateTime.Now);
} // close second Action `the async task`
) // end of Parallel.Invoke
} // End of Main
} // End of Program
I was able to the await statement work correctly to reach the required point, but the lock the condition if(duration == TimeSpan.Zero) never become true
First of all your program can't work as you showed because your TimeSpan duration = DateTime.Parse(midNight).Subtract(DateTime.Now); never will be positive. Second you main function will return almost immediately. Anyway you can try my solution for your problem:
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
public static void Main(string[] args)
{
Parallel.Invoke(
() =>{Console.WriteLine("Begin first task...");},
async () =>
{
Console.WriteLine("Begin second task...");
DateTime startDate = DateTime.Today;
while (true)
{
TimeSpan duration = DateTime.Now.Subtract(startDate);
Console.WriteLine("looping at: {0:00} Days, {1:00} Hours, {2:00} Minutes, {3:00} Seconds, {4:00} Milliseconds",
duration.Days, duration.Hours, duration.Minutes, duration.Seconds, duration.Milliseconds);
int delay = (int)(DateTime.Today.AddDays(1.0).Subtract(DateTime.Now).TotalMilliseconds/2);
await Task.Delay(delay>0?delay:0);
if(duration.Days >= 1)
{
Console.WriteLine("It is time... midnight is {0}", DateTime.Now);
startDate = DateTime.Today;
}
}
}
);
}
}
This will not provide you super precision as on normal PC you can't get it (you could use IRQ to get better accuracy but solution like that is far more complex).
Also as prof of concept link to 10s version.
At time version:
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
public static void Main(string[] args)
{
Parallel.Invoke(
async () =>
{
Console.WriteLine("Begin second task...");
TimeSpan eventTime = new TimeSpan(0,18,16,53,123); //set when run event (ex. 18:16:53.123)
DateTime endDate = DateTime.Today.Add(eventTime);
if(endDate<DateTime.Now) endDate = endDate.AddDays(1.0);
while (true)
{
TimeSpan duration = endDate.Subtract(DateTime.Now);
Console.WriteLine("looping at: {0:00} Days, {1:00} Hours, {2:00} Minutes, {3:00} Seconds, {4:00} Milliseconds", duration.Days, duration.Hours, duration.Minutes, duration.Seconds, duration.Milliseconds);
if(duration.TotalMilliseconds <= 0.0)
{
Console.WriteLine("It is time... {0}", DateTime.Now);
endDate = endDate.AddDays(1.0);
continue;
}
int delay = (int)(duration.TotalMilliseconds/2);
await Task.Delay(delay>0?delay:0);
}
}
);
Thread.Sleep(6000);
}
}
I was able to do it by changing the condition from:
if(duration == TimeSpan.Zero)
to:
if(duration.Days == 0 && duration.Hours == 0 && duration.Minutes == 0 && duration.Seconds == 0)
and to avoid the double occurrence of the event, i added another await level, so the new one became like:
if(duration.Days >= 1)
await Task.Delay(8640000);
else if(duration.Hours >= 1)
await Task.Delay(360000);
else if(duration.Minutes >= 1)
await Task.Delay(60000);
else if(duration.Seconds >= 1)
await Task.Delay(1000);
else
await Task.Delay(500);
I tried adding the if(duration.Milliseconds >= 1) await(1) but did not work, my output became as shown below:
The problem is that in your case, the duration is never zero, it goes from plus some milliseconds to minus some milliseconds.
What I would do: If duration is less than one second, wait for duration and then just assume it's the right time. In code:
if (duration.Days >= 1)
await Task.Delay(8640000);
else if (duration.Hours >= 1)
await Task.Delay(360000);
else if (duration.Minutes >= 1)
await Task.Delay(60000);
else if (duration.Seconds >= 1)
await Task.Delay(1000);
else
{
// defensive check in case duration is already negative
// this should not normally happen, but is still possible
if (duration > TimeSpan.Zero)
await Task.Delay(duration);
Console.WriteLine("It is time... midnight is {0}", DateTime.Now);
}
This won't give you millisecond accuracy, but it should be the right second, under normal circumstances.

How to make a count timer C#

I'm trying to create a timer in c# for an online game. All i really want is a timer that counts 60 seconds and then restarts. And let it go forever, then add a point for every time it resets...
What i've done so far is:
DateTime dateTime = DateTime.Now;
int sec = dateTime.Second;
if(sec = 1)
{
// stuff
}
The if does not loop, how do I do that? or anyone have a better idea? I'd really like one where i can change the seconds.
I think System.Threading.Timer might be useful, just set a callback that triggers after 60 seconds.
i found something related to my question and edited to what i wanted. it does what I want it to do, but does it create overflow or not, that im not sure of. Does anyone have a better idea of doing this?
using System;
namespace ticket
{
class Program
{
public static int x = 0;
static void LoopingFunction()
{
while (x <= 20)
{
int dwStartTime = System.Environment.TickCount;
while (true)
{
if (System.Environment.TickCount - dwStartTime > 100) break; //100 milliseconds
}
Console.WriteLine(x);
x++;
if (x == 20)
{
///add "stuff"
Console.WriteLine("Test");
x = 0;
}
}
}
static void Main()
{
LoopingFunction();
Console.Read();
}
}
}

Categories