C# Windows Application Timer Stops - c#

I have an Windows Application which uses timer like in the screen:
timer it's used to run a method every X minutes between 08:00:00 (Start Time) and 21:00:00 (Stop Time)
In the screen:
Next download Start at: shows what time the next run will occur
Time Left: shows the remaining time until next run will occur
Download Interval: time span between two runs
The method runs when the Next download Start = Current Time.
My issue is that event that the application is open and runs, the timer just stops after a while.
Any ideas why this happens, is this normal or am I doing something wrong in my code (i can post it if needed but now I was just asking to see if it's normal)?
Is there a way to prevent it or shell I create a checker and check his status regularly?
Thanks in advance for your support!
private System.Windows.Forms.Timer timerFrequency = new System.Windows.Forms.Timer();
public void LoadGeneraInfoPanel()
{
timerFrequency.Interval = 1000;
timerFrequency.Enabled = true;
this.timerFrequency.Tick += new System.EventHandler(this.timerFrequency_Tick);
timerFrequency.Start();
}
private void timerFrequency_Tick(object sender, EventArgs e)
{
txtGICurrTime.Text = DateTime.Now.ToString("HH:mm:ss");
if (drSystemParam["Auto"].ToString() == "True" && timerFrequency.Enabled)
{
if (txtGIFrequency.Text.ToString() != string.Empty && txtGIStopTime.Text.ToString() != string.Empty && txtGIStartTime.Text.ToString() != string.Empty)
{
int iHours = Convert.ToInt32(txtGIFrequency.Text.Substring(0, 2));
int iMinutes = Convert.ToInt32(txtGIFrequency.Text.Substring(3, 2));
int iSeconds = Convert.ToInt32(txtGIFrequency.Text.Substring(6, 2));
DateTime dCurrStartTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, Convert.ToInt32(txtGIStartTime.Text.Substring(0, 2)), Convert.ToInt32(txtGIStartTime.Text.Substring(3, 2)), Convert.ToInt32(txtGIStartTime.Text.Substring(6, 2)));
DateTime dCurrStopTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, Convert.ToInt32(txtGIStopTime.Text.Substring(0, 2)), Convert.ToInt32(txtGIStopTime.Text.Substring(3, 2)), Convert.ToInt32(txtGIStopTime.Text.Substring(6, 2)));
DateTime dCurrStartDownloadTime = dCurrStartTime;
for (int j = 0; dCurrStartDownloadTime < DateTime.Now & dCurrStartDownloadTime <= dCurrStopTime; j++)
dCurrStartDownloadTime = dCurrStartDownloadTime.AddHours(iHours).AddMinutes(iMinutes).AddSeconds(iSeconds);
var result = dCurrStartDownloadTime;
if (DateTime.Now > dCurrStartTime && DateTime.Now < dCurrStopTime.AddHours(-iHours).AddMinutes(-iMinutes).AddSeconds(-iSeconds))
{
if (txtNextDownloadTime.Text == String.Empty)
txtNextDownloadTime.Text = result.ToString("HH:mm:ss");
TimeSpan diff = result - DateTime.Now.AddSeconds(-1);
txtGITimeLeft.Text = string.Format("{0}:{1}:{2}", diff.Hours.ToString().PadLeft(2, '0'), diff.Minutes.ToString().PadLeft(2, '0'), diff.Seconds.ToString().PadLeft(2, '0'));
if (DateTime.Now.ToString("HH:mm:ss") == txtNextDownloadTime.Text)
{
timerFrequency.Stop();
txtNextDownloadTime.Text = result.ToString("HH:mm:ss");
Thread.Sleep(800);
timerFrequency.Enabled = true;
timerFrequency.Start();
btnEecuteMethod_Click(sender, e);
}
}
else
{
result = dCurrStartTime.AddDays(1);
txtNextDownloadTime.Text = result.ToString("HH:mm:ss");
TimeSpan diff = result - DateTime.Now.AddSeconds(-1);
txtGITimeLeft.Text = string.Format("{0}:{1}:{2}", diff.Hours.ToString().PadLeft(2, '0'), diff.Minutes.ToString().PadLeft(2, '0'), diff.Seconds.ToString().PadLeft(2, '0'));
}
}
else
{
timerFrequency.Enabled = false;
timerFrequency.Stop();
}
}
}

Related

Timer Goes Negative

I am facing an issue with my timer. The issue is, timer goes negative after reaching the specified time limit and the next levels never unlocks. This only happens whenever I change my timespan to 24 hours. When I am using seconds or minutes the timer stops when it reaches to zero (0) and make the button interactable again. I have also tested it on 1 hour and it works fine.
IEnumerator TimeUpdate()
{
if (bonus != null)
{
if (PlayerPrefs.GetInt("Bonus", 0) == 0)
{
bonus.interactable = true;
showTimer.gameObject.SetActive(false);
PlayerPrefs.SetString("BONUS_END_TIME", "");
StopAllCoroutines();
}
else
{
bonus.interactable = false;
showTimer.gameObject.SetActive(true);
}
}
while (true)
{
chkbonustime();
DateTime dt = DateTime.Now;
string bonusendtime = PlayerPrefs.GetString("BONUS_END_TIME", "");
DateTime dateComplete;
if (bonusendtime != null)
{
dateComplete = DateTime.Parse(bonusendtime);
DateTime ENDTIME = dateComplete.Add(TimeSpan.FromHours(24));
TimeSpan ABC = ENDTIME - dt;
showTimer.text = ABC.Hours + " : " + ABC.Minutes + " : " + ABC.Seconds;
}
// Debug.Log();
yield return new WaitForSeconds(1);
}
}
public void chkbonustime()
{
string bonusendtime = PlayerPrefs.GetString("BONUS_END_TIME", "");
if (!bonusendtime.Equals(""))
{
DateTime dateComplete = DateTime.Parse(bonusendtime);
DateTime xyz = DateTime.Now;
TimeSpan timespan = xyz - dateComplete;
Debug.Log(timespan.Seconds);
if (timespan.Hours >= 24)
{
// if (PlayerPrefs.GetInt("Bonus", 0) == 1)
// {
PlayerPrefs.SetInt("Bonus", 0);
bonus.interactable = true;
showTimer.gameObject.SetActive(false);
PlayerPrefs.SetString("BONUS_END_TIME", "");
StopAllCoroutines();
// }
// else
// {
// bonus.interactable = false;
// showTimer.gameObject.SetActive(true);
// }
}
//else
// return false;
// PlayerPrefs.SetString("BONUS_END_TIME", "");
}
else
{
// return false;
}
}
Hours is only between 0-23, you likely want TotalHours or TotalDays.

if statement keeps triggering

I am fairly new to C# (using it for a crpytographic process).
Some help would be greatly appreciated!
I have made a timer that should print out my hash speed every minute. See code below
using System;
using System.Text;
using System.Security.Cryptography;
namespace HashConsoleApp {
class Program {
static void Main(string[] args) {
long Nonce = 19989878659;
long Noncestart = 19989878659;
int Tick = 0;
DateTime start = DateTime.UtcNow;
while (Tick == 0) {
string noncestr = Nonce.ToString();
string plainData = "1" + noncestr + "Sjoerd0000000000000000000000000000000000000000000000000000000000000000";
string hashedData = ComputeSha256Hash(plainData);
// if 10-zeroes hash is found, save to disk
if (hashedData.Substring(0, 10) == "0000000000") {
Tick = Tick + 1;
string writestring = "Nonce: " + noncestr + "\n" + "hashed data: " + hashedData;
System.IO.File.WriteAllText("hash_10.txt", writestring);
}
// print hash speed per second, each minute
DateTime end = DateTime.UtcNow;
TimeSpan span1 = end.Subtract(start);
TimeSpan span2 = end.Subtract(start);
if (span1.Minutes >= 1) {
long diff = (int)(Nonce - Noncestart) / 60;
string diffs = diff.ToString();
Console.Write("Hash speed: " + diffs + " h/s");
System.IO.File.WriteAllText("test.txt", Nonce.ToString());
Noncestart = Nonce;
span1 = TimeSpan.Zero;
}
// save Nonce every hour, reset clock
if (span2.Minutes >= 60) {
start = DateTime.UtcNow;
System.IO.File.WriteAllText("hourly_nonce.txt", Nonce.ToString());
span2 = TimeSpan.Zero;
}
//Console.WriteLine("Raw data: {0}", plainData);
//Console.WriteLine("Hash {0}", hashedData);
//Console.WriteLine(ComputeSha256Hash("1"+noncestr+"Sjoerd0000000000000000000000000000000000000000000000000000000000000000"));
}
}
static string ComputeSha256Hash(string rawData) {
// Create a SHA256
using(SHA256 sha256Hash = SHA256.Create()) {
// ComputeHash - returns byte array
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
// Convert byte array to a string
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.Length; i++) {
builder.Append(bytes[i].ToString("x2"));
}
return builder.ToString();
}
}
}
}
However, after the 1 minute mark this repeadetly keeps on printing on my screen. it looks like it gets stuck in the if statement. Is there something wrong with my code?
This should do the trick for your minute-timer (resetting minuteStart instead of span1):
static void Main(string[] args) {
long Nonce = 19989878659;
long Noncestart = 19989878659;
int Tick = 0;
DateTime start = DateTime.UtcNow;
DateTime minuteStart = DateTime.UtcNow; // ##### (added)
while (Tick == 0) {
// [Process stuff]
// print hash speed per second, each minute
DateTime end = DateTime.UtcNow;
TimeSpan span1 = end.Subtract(minuteStart); // ##### (modified)
if (span1.TotalMinutes >= 1) { // ##### (modified but Minutes should work fine here)
long diff = (int)(Nonce - Noncestart) / 60;
string diffs = diff.ToString();
Console.Write("Hash speed: " + diffs + " h/s");
System.IO.File.WriteAllText("test.txt", Nonce.ToString());
Noncestart = Nonce;
minuteStart = DateTime.UtcNow; // ##### (added)
//span1 = TimeSpan.Zero; // ##### (deleted)
}
// [...]
}
}
(See the lines with // #### comments)
The trick is that resetting span1 is useless because of this line:
TimeSpan span1 = end.Subtract(start);
However, if (span2.Minutes >= 60) will never be entered, as TimeSpan.Minutes "ranges from -59 through 59".
You probably are looking for TotalMinutes here.
Your if (span1.Minutes >= 1) { statement won't mean the printout only occurs once per minute, it will simply cause it to print whenever at least one minute has passed since the program started.
You need to check whether 1 minute has passed since the last printout . Therefore you need to reset the start time every time you run a printout. (N.B. Setting span1 = TimeSpan.Zero as you do now has no effect because you just overwrite that as soon as the loop runs again).
Also your minute and hour tests will conflict with each other once you do this, so you need separate date counters.
So add
DateTime start2 = DateTime.UtcNow;
just below the line where you declare start already.
Then please replace span1 = TimeSpan.Zero; with
start2 = DateTime.UtcNow;
and change TimeSpan span1 = end.Subtract(start);
to
TimeSpan span1 = end.Subtract(start2);
Lastly, replace if (span2.Minutes >= 60) { with
if (span2.TotalMinutes >= 60) {
otherwise this part won't work either because Minutes only reports the minutes in the current hour. You can also remove span2 = TimeSpan.Zero;, this is redundant like the similar line in the first if block.

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);
}
}
}

Date/Time Picker unable to loop properly

Want to do a loop of picture slideshow to start from a specific time and then to end at another specific time.
Also, how to set the DateTime picker to select minutes/hours?
//Under start button
if (rbtnDateTime.Checked == true)
{
DateTime startDate = dateTimePicker1.Value.Date;
DateTime stopDate = dateTimePicker2.Value.Date;
//Given time interval in seconds
if (mtxtSlideShowInterval.Text != "")
{
int interval = Convert.ToInt16(mtxtSlideShowInterval.Text);
while ((startDate = startDate.AddSeconds(interval)) <= stopDate)
{
timerSlideShow.Enabled = true;
timerSlideShow.Start();
}
timerSlideShow.Stop();
timerSlideShow.Enabled = false;
}
}
//Under timer_tick event
//Infinite Loop
else
{
if (listBoxPicturesInAlbum.SelectedIndex ==listBoxPicturesInAlbum.Items.Count - 1)
{
listBoxPicturesInAlbum.SelectedIndex = 0;
}
else
{
listBoxPicturesInAlbum.SelectedIndex++;
}
}
I would be rid of the while loop you have, and take a few steps.
First, you'll need a field to mark your current index:
int currentImageIndex = 0;
Second, you'll set your timer.Interval.
timer.Interval = int.Parse(mtxtSlideShowInterval.Text) * 1000;
Third, your timer_tick can include something like this:
if (DateTime.Now < dateTimePicker2.Value.Date)
{
listBoxPicturesInAlbum.SelectedIndex = currentImageIndex;
pictureBox.Image = Image.FromFile((string)listBoxPicturesInAlbum.SelectedValue);
currentImageIndex = (currentImageIndex + 1) % listBoxPicturesInAlbum.Items.Count;
}

Windows service and timer in C#

I need help to write a windows service with a timer that can call 3 different function(events) in 3 different times every day.
Some code example please. Thank you.
private System.Timers.Timer timer;
protected override void OnStart(string[] args)
{
this.timer1 = new System.Timers.Timer(60000);
this.timer1.AutoReset = true;
this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);
this.timer1.Start();
}
private DateTime _lastRun1 = DateTime.Now.AddDays(-1);
private DateTime _lastRun2 = DateTime.Now.AddDays(-1);
private DateTime _lastRun3 = DateTime.Now.AddDays(-1);
private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (_lastRun.Date < DateTime.Now.Date && DateTime.Now.Hour == 13)
{
//call functionX
DateTime _lastRun1 = DateTime.Now.AddDays(1);
}
if (_lastRun.Date < DateTime.Now.Date && DateTime.Now.Hour == 14)
{
//call functionY
DateTime _lastRun2 = DateTime.Now.AddDays(1);
}
if (_lastRun.Date < DateTime.Now.Date && DateTime.Now.Hour == 16)
{
//call functionXY
DateTime _lastRun3 = DateTime.Now.AddDays(1);
}
}
Why not just write 3 distinct applications and let the Windows task scheduler execute them at the appropriate times? This will probably be a lot easier than trying to get your own scheduling logic right, which can often be more complicated than you'd expect.

Categories