I am fairly new to threading in general and i want to try it in C#. I am trying to make a basic simulation of tonnage of something which is decaying every 20 seconds and being refilled every 10 seconds. From what i read, thread safety is something i need to consider as there are two threads; one for decaying the variable tonnage by 160, one for adding a random amount to the tonnage and since they are making transactions to the variable tonnage, i should make sure they are accessed correctly.
I read on how to use lock(object) and i understand the concept for simple thread examples but how do i use it for 2 threads running forever and have to make timely adjustments in the tonnage?
Here is what i have, but when i lock the whole loop, the other thread never spawns. Or do i have the wrong code structure?
public double tonnage = 1000;
private object x = new object();
//Starts the simulation, runs forever until user ends the simulation
private void btnStart_Click(object sender, EventArgs e)
{
//Decay Tonnage
Thread decayTonnageThread = new Thread(() => decayTonnage (tonnage));
decayTonnageThread .Start();
//Add Tonnage
Thread addTonnageThread = new Thread(() => addTonnage (tonnage));
addTonnageThread .Start();
}
//I want to decay the tonnage every 20 seconds
public void decayTonnage (double tonnage)
{
lock(x)
{
while (true)
{
tonnage = tonnage - 160;
Thread.Sleep(20000);
}
}
}
//Add to the tonnage every 10 seconds
public void addTonnage (double tonnage)
{
lock(x)
{
while (true)
{
Random random = new Random();
double randomNumber = random.Next(97, 102);
tonnage = tonnage + randomNumber;
Thread.Sleep(10000);
}
}
}
You want the lock to be as small as possible, only have it around the lines that are interacting with shared objects, not the entire loop. Also, putting Random random = new Random(); in the while loop is a bad habit to have, you should make only one random instance and initialize it outside of the loop.
//I want to decay the tonnage every 20 seconds
public void decayTonnage (double tonnage)
{
while (true)
{
lock(x)
{
tonnage = tonnage - 160;
}
Thread.Sleep(20000);
}
}
//Add to the tonnage every 10 seconds
public void addTonnage (double tonnage)
{
Random random = new Random();
while (true)
{
double randomNumber = random.Next(97, 102);
lock(x)
{
tonnage = tonnage + randomNumber;
}
Thread.Sleep(10000);
}
}
Also, I assume you are doing this for some kind of assignment and must use threads, but if I was doing this for real I would not use threads with loops + a Sleep at all and instead use two timers, one that fired every 20 seconds and one that fired every 10 seconds. Depending on the type of timer you use you may or may-not still need to use a lock.
Related
How do I wait for a specified time while showing the remaining time to wait?
I now solved it like this but I feel like this is a really bad way to do it:
//This is running in a BackgroundWorker:
Stopwatch watch = new Stopwatch();
watch.Start();
while(watch.ElapsedMilliseconds != SecondsToWait * 1000)
{
TimeToNextRefresh = ((SecondsToWait * 1000) - watch.ElapsedMilliseconds) / 1000;
Thread.Sleep(1);
}
watch.Stop();
So here I am guessing that the condition (watch.ElapsedMilliseconds != SecondsToWait * 1000) is checked every millisecond.
So the main question is; In what period is the condition of while checked and/or how do I improve the code I've written?
It depends on what's the code inside while loop!
For example, if you write some really long/time-consuming code in a while loop, each iteration of the while loop, or course, will be longer than a while loop that only has short/fast code.
Compare these two while loops:
while (true) {
Console.WriteLine("Hello");
}
and
while (true) {
Console.Beep(5000);
}
Each iteration of the first while loop is faster than that of the second one because Console.Beep(5000) takes 5 seconds and Console.WriteLine only takes a fraction of a second.
So you can't rely on while loops to count time.
This is what you should do:
Create an instance of System.Windows.Forms.Timer, not the System.Timers.Timer nor the System.Threading.Timer. I find the first one the most useful (others are more advanced).
Timer timer = new Timer();
timer.Interval = 1000; // 1000 means 1000ms aka 1 second
timer.Tick += TimerTicked;
timer.Start();
Now the compiler will tell you that TimerTicked is not defined, so let's go define that:
private void TimerTicked(object sender, EventArgs e) {
}
Now you're all set. The code in TimerTicked will be called every one second.
Let's say you want to measure a time of 10 seconds. After 10 seconds, you want to do something. So first create a variable called secondsLeft in the class level:
int secondsLeft = 10;
Now in TimerTicked, you want to check whether secondsLeft is 0. If it is, do that something, else, minus one:
if (secondsLeft == 0) {
DoSomething();
} else {
secondsLeft--;
}
And secondsLeft is the time remaining! You can display it on a label or something.
To pause the timer, simply
timer.Stop();
The exact interval in which your while condition is checked is hard to predict. Thread.Sleep(1); only tells the operating system that you want your thread to sleep for at least 1 millisecond. There is no guarantee that your thread will be active again after exactly 1ms. Actually you can rather be sure that it will be more than that. The thread is scheduled again after 1ms, but there will be a delay until he gets his CPU time slot.
The interval you want for your loop actually depends how you want to display the remaining time. If you want to display only seconds, why would you update that display every millisecond, although the text would change only every 1000ms?
A loop like that is probably not a good way to implement something like that. I would recommend a System.Threading.Timer:
// this Timer will call TimerTick every 1000ms
Timer timer = new Timer(TimerTick, null, 0, 1000);
and implement the handler
public void TimerTick(object sender)
{
// update your display
}
Note that you will have the "update your display" part on the UI thread again, as this method is called by the Timer on a different thread.
This code is can really make an infinite loop if a calculation just take longer than 1 miliseconds.
You can achieve your desired behaviour with a simple System.Winforms.Forms.Timer like this snipped below :
private int tickCount = 0;
private int remaining = 10;
private void timer1_Tick(object sender, EventArgs e)
{
remaining--;
textBox1.Text = remaining.ToString();
}
private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 1000;
timer1.Enabled = true;
}
With this you can countdown from 10 seconds and every tick you write to a textbox the remaining seconds
actually i have to create lots of threads to send pcap file using UDP protocol, when thread completely sends the pcap file it then sleep for some time. when i sleep thread to 420 seconds virtual memory gets full after creating more than 3100 threads and program throws a OutOfMemoryException.
i searched internet about this problem but found that a thread takes only 1MB to create and pcap file is just 60KB, and my 3100 threads are consuming more than 12GB(1.06*3100<12GB). on the other hand physical memory is not used more than 200MB. i have to create more than 5000 threads at the same time
what am i doing wrong? can anyone help me?
thanks
my code:
public static void send_pcap_file_with_single_port()
{
string callID = Call_ID;
try
{
//CREATING CONNECTION HERE
using (FileStream stream = new FileStream("g711a.pcap", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
for (Pos = 0; Pos < (StreamBytes - ChunkSize); Pos += ChunkSize)
{
//creating RTP_header here
stream.Read(RTP_payload, 0, ChunkSize);
//combining both the byte arrays
System.Buffer.BlockCopy(RTP_header, 0, Bytes_to_send, 0, RTP_header.Length);
System.Buffer.BlockCopy(RTP_payload, 0, Bytes_to_send, 16, RTP_payload.Length);
RTPpacket_queue.Enqueue(Bytes_to_send);
//RTP_handler.Send(Bytes_to_send, Bytes_to_send.Length, remote_EP);
}
//done processing here
stream.Close();
stream.Dispose();
RTP_count++;
GC.Collect();
}
System.Threading.Thread.Sleep(420000);
}
catch (Exception e)
{
//using (StreamWriter sw = new StreamWriter(stream_logFile))
//{
// sw.WriteLine(e.ToString());
//}
//send_BYE_message_toSIPp(client, "BYE", 5060, 2, callID);
Console.WriteLine(e.ToString());
}
}
creating threads here:
Thread RTP_sender = new Thread(new ThreadStart(send_pcap_file_with_single_port));
RTP_sender.Start();
In simple terms you exhaust you garbage collector by creating objects in long term pile (objects that survive longer then few seconds). Fix would be to free and recreate thread when it is needed.
In any case by default i5 has 2 cores, if you have 3 or more threads than they are running them on same cpu. Running 3000+ of them means 1500 each, it is not a problem unless they try to write in same place (in case they start blocking like hell).
To demonstrate you do not need 5000 permanent threads to accomplish something like this, I have created a sample program.
The program does not do much really but what it does do is that it creates 5000 objects, each of which creates a thread when it needs to do its work. There isn't any actual work being done other than simply sleeping for a random interval but still.
Just run the program, leave it running for a while and keep an eye on its memory use. You will see it is very much manageable while still actually doing work on 5000 objects.
You will probably need to actually be creative in applying this approach to your situation but you could do something along the lines of what I am doing.
namespace Test
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
public static class MainClass
{
public static Random sleeper = new Random ();
public static void Main (string[] args)
{
Stopwatch timer = new Stopwatch ();
List<WorkerClass> workload = new List<WorkerClass> ();
// Create a workload of 5000 objects
for (int i = 0; i < 5000; i++) {
workload.Add (new WorkerClass ());
}
int fires = 0;
// Start processing the workload
while (true) {
// We'll measure the time it took to go through the entire workload
// to illustrate that it does not take all that long.
timer.Restart ();
foreach (WorkerClass w in workload) {
// for each of the worker objects in the entire workload
// we decrease its internal counter by 1.
// Because after the loop is done, we sleep for 1 secondd
// that amounts to reducing the counter by 1 every second.
w.counter--;
if (w.counter == 0) {
fires++;
// Once the counter hits 0, do the work.
w.DoWork ();
}
}
timer.Stop ();
Console.WriteLine ("Processing the entire workload of {0} objects took {1} milliseconds, {2} workers actually fired.", workload.Count, timer.ElapsedMilliseconds, fires);
fires = 0;
Thread.Sleep (1000);
}
}
}
public class WorkerClass
{
public int counter = 0;
public WorkerClass ()
{
// When the worker is created, set its internal counter
// to a random value between 5 and 10.
// This is to mimic sleeping it for a random interval.
// Also see the primary loop in MainClass.Main
this.counter = MainClass.sleeper.Next (5, 10);
}
public void DoWork ()
{
// Whenever we do the work, we'll create a background worker thread
// that actually does the work.
BackgroundWorker work = new BackgroundWorker ();
work.RunWorkerCompleted += (object sender, RunWorkerCompletedEventArgs e) => {
// This simulates going back to sleep for a random interval, see
// the main loop in MainClass.Main
this.counter = MainClass.sleeper.Next (5, 10);
};
work.DoWork += (object sender, DoWorkEventArgs e) => {
// Simulate working by sleeping a random interval
Thread.Sleep (MainClass.sleeper.Next (2000, 5000));
};
// And now we actually do the work.
work.RunWorkerAsync ();
}
}
}
I have an application that generates random numbers for about 20 seconds and shows the random number on the fly in a label in the screen.
I want to show the numbers in the same label but then slow down the display of the numbers so like 5 seconds before stoping the process, the display of the number should smoothly slow down more and more until it stops in the final number. Like a raffle.
Any clue?
I can start by telling you what not do to. Do not use Thread.Sleep -- doing so is almost always a "worst practice" and will make your UI unresponsive.
If you use Thread.Sleep on a second thread, as mcl suggests, you won't freeze your UI but you are burning an extremely expensive thread to do very little work.
If you are using C# 4 or earlier then I would create a timer set to tick, say, four times a second. Handle the tick event, and if enough time has passed since the last tick event, change the label. Or, change the interval of the timer each time it ticks.
If you are using C# 5, you can just use await Task.Delay(x):
async void Animate()
{
int delay = 5;
for(int i = 1; i < 10; ++i)
{
UpdateLabel();
await Task.Delay(delay);
delay = delay * 2;
}
}
So now you start with a 5ms delay, then 10, then 20...
Here's a working program to get you started. It changes the Text of the Form for 3 seconds quickly, after which it gets slower. That's achieved by using one Timer to start decelerating the Timer which shows the random numbers.
public partial class Form1 : Form
{
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer() { Interval = 10 };
System.Windows.Forms.Timer timerForStartingSlowDown = new System.Windows.Forms.Timer() { Interval = 3000 };
bool slow = false;
Random random = new Random();
public Form1()
{
InitializeComponent();
timer.Tick += timer_Tick;
timerForStartingSlowDown.Tick += timerForStartingSlowDown_Tick;
Shown += Form1_Shown;
}
void timerForStartingSlowDown_Tick(object sender, EventArgs e)
{
slow = true;
timerForStartingSlowDown.Enabled = false;
}
void Form1_Shown(object sender, EventArgs e)
{
timer.Enabled = true;
timerForStartingSlowDown.Enabled = true;
}
void timer_Tick(object sender, EventArgs e)
{
if (timer.Interval > 350) timer.Enabled = false;
else
{
if (slow) timer.Interval += 10;
Text = random.Next(1, 100).ToString();
}
}
}
Consider generating those numbers on a different thread. You can use BackgroundWorker for that and report the progress as you generate each number. When you begin to reach the end use Thread.Sleep(miliseconds) to "slow" (freez) the BackgroundWorker's job thread that is generating the numbers for a specified amount of miliseconds increasing those miliseconds as you aproach the final number. That should do the trick.
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Set the BackgroundWorker to report progress and use that to "push" the generated number to the UI thread.
You can also drag and drop the BackgroundWorker component on your form from the Toolbox.
I have a main thread which is controlling a windows form, upon pressing a button two threads are executed. One is used for recording information, the other is used for reading it. The idea behind putting these in threads is to enable the user to interact with the interface while they are executing.
Here is the creating of the two threads;
Thread recordThread = new Thread(() => RecordData(data));
recordThread.Name = "record";
recordThread.Start();
Thread readThread = new Thread(() => ReadData(data));
readThread.Name = "read";
readThread.Start();
The data is simply a Data-object that stores the data that is recorded during the recording.
The problem that I am facing is that the first thread is executed fine, the second refuses to run until the first one completes. Putting a breakpoint in the second threads function, ReadData lets me know that it is only called after the first thread is done with all of its recording.
I have been trying to solve this for a few hours now and I can't get my head around why it would do this. Adding a;
while(readThread.IsAlive) { }
right after the start will halt the execution of anything after that, and it's state is Running. But it will not go to the given method.
Any ideas?
Edit:
The two functions that are called upon by the threads are;
private void RecordData(Data d)
{
int i = 0;
while (i < time * freq)
{
double[] data = daq.Read();
d.AddData(data);
i++;
}
}
private void ReadData(Data d)
{
UpdateLabelDelegate updateData =
new UpdateLabelDelegate(UpdateLabel);
int i = 0;
while (i < time * freq)
{
double[] data = d.ReadLastData();
this.Invoke(updateData, new object[] { data });
i++;
}
}
The data object has locking in both the functions that are called upon; ReadLastData and Read.
Here are the methods in the Data object.
public void AddData(double[] data)
{
lock (this)
{
int i = 0;
foreach (double d in data)
{
movementData[i].Add(d);
i++;
}
}
}
public double[] ReadLastData()
{
double[] data = new double[channels];
lock (this)
{
int i = 0;
foreach (List<double> list in movementData)
{
data[i] = list[list.Count - 1];
}
}
return data;
}
Looks like you have a race condition between your reading/writing. In your first thread you lock down the object whilst you add data to it and in the second thread you attempt to get an exclusive lock on it to start reading. However, the problem is the first thread is executing so fast that the second thread never really gets a chance to acquire the lock.
The solution to this problem really depends on what sort of behaviour you are after here. If you expect after every write you get a consecutive read then what you need to do is control the execution between the reading/writing operations e.g.
static AutoResetEvent canWrite = new AutoResetEvent(true); // default to true so the first write happens
static AutoResetEvent canRead = new AutoResetEvent(false);
...
private void RecordData(Data d)
{
int i = 0;
while (i < time * freq)
{
double[] data = daq.Read();
canWrite.WaitOne(); // wait for the second thread to finish reading
d.AddData(data);
canRead.Set(); // let the second thread know we have finished writing
i++;
}
}
private void ReadData(Data d)
{
UpdateLabelDelegate updateData =
new UpdateLabelDelegate(UpdateLabel);
int i = 0;
while (i < time * freq)
{
canRead.WaitOne(); // wait for the first thread to finish writing
double[] data = d.ReadLastData();
canWrite.Set(); // let the first thread know we have finished reading
this.Invoke(updateData, new object[] { data });
i++;
}
}
Could you try adding a Sleep inside RecordData?
Maybe it's just your (mono cpu??) windows operating system that doesn't let the second thread get its hand on cpu resources.
Don't do this:
lock (this)
Do something like this instead:
private object oLock = new object();
[...]
lock (this.oLock)
EDIT:
Could you try calls like this:
Thread recordThread = new Thread((o) => RecordData((Data)o));
recordThread.Name = "record";
recordThread.Start(data);
I want to do stuff every minute on the minute (by the clock) in a windows forms app using c#. I'm just wondering whats the best way to go about it ?
I could use a timer and set its interval to 60000, but to get it to run on the minute, I would have to enable it on the minute precisely, not really viable.
I could use a timer and set its interval to 1000. Then within its tick event, I could check the clocks current minute against a variable that I set, if the minute has changed then run my code. This worries me because I am making my computer do a check every 1 second in order to carry out work every 1 minutes. Surely this is ugly ?
I'm using windows forms and .Net 2.0 so do not want to use the DispatchTimer that comes with .Net 3.5
This must be a fairly common problem. Have any of you a better way to do this?
Building on the answer from aquinas which can drift and which doesn't tick exactly on the minute just within one second of the minute:
static System.Timers.Timer t;
static void Main(string[] args)
{
t = new System.Timers.Timer();
t.AutoReset = false;
t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
t.Interval = GetInterval();
t.Start();
Console.ReadLine();
}
static double GetInterval()
{
DateTime now = DateTime.Now;
return ((60 - now.Second) * 1000 - now.Millisecond);
}
static void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine(DateTime.Now.ToString("o"));
t.Interval = GetInterval();
t.Start();
}
On my box this code ticks consistently within .02s of each minute:
2010-01-15T16:42:00.0040001-05:00
2010-01-15T16:43:00.0014318-05:00
2010-01-15T16:44:00.0128643-05:00
2010-01-15T16:45:00.0132961-05:00
How about:
int startin = 60 - DateTime.Now.Second;
var t = new System.Threading.Timer(o => Console.WriteLine("Hello"),
null, startin * 1000, 60000);
Creating a Timer control that fires every 1 second (and usually does nothing but a simple check) will add negligible overhead to your application.
Simply compare the value of Environment.TickCount or DateTime.Now to the last stored time (the previous 'minute tick'), and you should have a reasonably precise solution. The resolution of these two time values is about 15ms, which should be sufficient for your purposes.
Do note however that the interval of the Timer control is not guaranteed to be that precise or even anywhere now, since it runs on the Windows message loop, which is tied in with the responsiveness of the UI. Never rely on it for even moderately precise timing - though it is good enough for firing repeating events where you can check the time using a more sensitive method such as one of the two given above.
You can nail this with reactive extensions which will take care of lots of timer related problems for you (clock changes, app hibernation etc). Use Nuget package Rx-Main and code like this:
Action work = () => Console.WriteLine(DateTime.Now.ToLongTimeString());
Scheduler.Default.Schedule(
// start in so many seconds
TimeSpan.FromSeconds(60 - DateTime.Now.Second),
// then run every minute
() => Scheduler.Default.SchedulePeriodic(TimeSpan.FromMinutes(1), work));
Console.WriteLine("Press return.");
Console.ReadLine();
Read here (search for "Introducing ISchedulerPeriodic") to see all the issues this is taking care of: http://blogs.msdn.com/b/rxteam/archive/2012/06/20/reactive-extensions-v2-0-release-candidate-available-now.aspx
I jsut wrote this class using the WPF DispatcherTimer but you can swap the dispatcher for any timer that supports changing when it's woken from sleep state.
The class is constructed with a fixed time step and supprts Start/Stop/Reset, Start/Stop/Start works like a resume operation. The timer is like a stopwatch in that regard.
A clock implementation would simply create the class with a interval of 1 second and listen to the event. Be wary though that this is a real-time clock, if the tick event takes longer than the interval to finish you'll notice that the clock will try and catch up to real-time this will cause a burst of tick events being raised.
public class FixedStepDispatcherTimer
{
/// <summary>
/// Occurs when the timer interval has elapsed.
/// </summary>
public event EventHandler Tick;
DispatcherTimer timer;
public bool IsRunning { get { return timer.IsEnabled; } }
long step, nextTick, n;
public TimeSpan Elapsed { get { return new TimeSpan(n * step); } }
public FixedStepDispatcherTimer(TimeSpan interval)
{
if (interval < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException("interval");
}
this.timer = new DispatcherTimer();
this.timer.Tick += new EventHandler(OnTimerTick);
this.step = interval.Ticks;
}
TimeSpan GetTimerInterval()
{
var interval = nextTick - DateTime.Now.Ticks;
if (interval > 0)
{
return new TimeSpan(interval);
}
return TimeSpan.Zero; // yield
}
void OnTimerTick(object sender, EventArgs e)
{
if (DateTime.Now.Ticks >= nextTick)
{
n++;
if (Tick != null)
{
Tick(this, EventArgs.Empty);
}
nextTick += step;
}
var interval = GetTimerInterval();
Trace.WriteLine(interval);
timer.Interval = interval;
}
public void Reset()
{
n = 0;
nextTick = 0;
}
public void Start()
{
var now = DateTime.Now.Ticks;
nextTick = now + (step - (nextTick % step));
timer.Interval = GetTimerInterval();
timer.Start();
}
public void Stop()
{
timer.Stop();
nextTick = DateTime.Now.Ticks % step;
}
}
Create a method or put this code where you want the timer to start:
int time = 60 - DateTime.Now.Second; // Gets seconds to next minute
refreshTimer.Interval = time * 1000;
refreshTimer.Start();
And then on your tick event set the interval to 60000:
private void refreshTimer_Tick(object sender, EventArgs e)
{
refreshTimer.Interval = 60000; // Sets interval to 60 seconds
// Insert Refresh logic
}
By making use of ReactiveExtensions you could use the following code if you were interested in doing something as simple as printing to the console.
using System;
using System.Reactive.Linq;
namespace ConsoleApplicationExample
{
class Program
{
static void Main()
{
Observable.Interval(TimeSpan.FromMinutes(1))
.Subscribe(_ =>
{
Console.WriteLine(DateTime.Now.ToString());
});
Console.WriteLine(DateTime.Now.ToString());
Console.ReadLine();
}
}
}
Running a bit of code to see if the minute has changed once per second should not require much CPU time, and should be acceptable.
What about Quartz.NET? I think its a good framework to do timed actions.
You could set up two timers. An initial short interval timer (perhaps to fire every second, but dependent on how presice the second timer must fire on the minute).
You would fire the short interval timer only until the desired start time of the main interval timer is reached. Once the initial time is reached, the second main interval timer can be activated, and the short interval timer can be deactivated.
void StartTimer()
{
shortIntervalTimer.Interval = 1000;
mainIntervalTimer.Interval = 60000;
shortIntervalTimer.Tick +=
new System.EventHandler(this.shortIntervalTimer_Tick);
mainIntervalTimer.Tick +=
new System.EventHandler(mainIntervalTimer_Tick);
shortIntervalTimer.Start();
}
private void shortIntervalTimer_Tick(object sender, System.EventArgs e)
{
if (DateTime.Now.Second == 0)
{
mainIntervalTimer.Start();
shortIntervalTimer.Stop();
}
}
private void mainIntervalTimer_Tick(object sender, System.EventArgs e)
{
// do what you need here //
}
Alternatively, you could sleep to pause execution until it times out which should be close to your desired time. This will only wake the computer when the sleep finishes so it'll save you CPU time and let the CPU power down between processing events.
This has the advantage of modifying the timeout so that it will not drift.
int timeout = 0;
while (true) {
timeout = (60 - DateTime.Now.Seconds) * 1000 - DateTime.Now.Millisecond;
Thread.Sleep(timeout);
// do your stuff here
}
Use a timer set to run every second (or millisecond, whatever your accuracy threshold is), and then code the method to run your functionality if and only if the current time is within that threshold past the "on the minute" point.
What I'm using for scheduled tasks is a System.Threading.Timer(System.Threading.TimerCallback, object, int, int) with the callback set to the code I want to execute based on the interval which is supplied in milliseconds for the period value.
What about a combination of aquinas' answer and 'polling': (apologies for the mixture of languages)
def waitForNearlyAMinute:
secsNow = DateTime.Now.Second;
waitFor = 55 - secsNow;
setupTimer(waitFor, pollForMinuteEdge)
def pollForMinuteEdge:
if (DateTime.Now.Second == 0):
print "Hello, World!";
waitForNearlyAMinute();
else:
setupTimer(0.5, pollForMinuteEdge)
I have a solution based on Environment.TickCount
static void Main(string[] args)
{
//constatnt total miliseconds to one minute
const Int32 minuteMilisecond = 60 * 1000;
//get actual datetime
DateTime actualDateTime = DateTime.UtcNow;
//compenzation to one minute
Int32 nexTimer = Environment.TickCount + ((59 - actualDateTime.Second) * 1000) + (999 - actualDateTime.Millisecond);
//random fuction to simulate different delays on thread
Random rnd = new Random();
//main loop
while (true)
{
if (Environment.TickCount > nexTimer)
{
nexTimer += minuteMilisecond;
//execute your code here every minute
Console.WriteLine($"actual DateTime: {DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss:ffff")}");
}
//random sleep between 100 - 200 ms
Thread.Sleep(rnd.Next(100, 200));
}
}