I have some code that spawns a few threads and invokes a Run() method on them.
What I want to do is to embed a timer into that loop which starts the threads and count how many threads have been completed.
The way I want to do that is by creating an entry in a List every time an IStuff is being ran and then count how many elements are in the list every second, and thus produce a per second result.
Not sure if I'm along the correct lines, but please suggest ways of doing that.
All you need is a variable in a shared scope, say int completionsPerSecond = 0 - and last thing your Run() method should do is increment it by 1.
Then you'd have a timer that every second, copies the value in completionsPerSecond to show you as your value, and then sets completionsPerSecond to 0.
Now every second, you'll know how many finished in the previous second.
Related
Is there a way to run the Timer so that it starts at exact full second?
stateTimer = new Timer(someCallback, null, 0, 1000);
This one will start right away, repeating each second, but the problem is it will start exactly when I run the program which may result in 13:14:15.230 start.
I would like 13:14:15.000 start. Something like:
stateTimer = new Timer(someCallback, null, DateTime.Now.Date, 1000);
Is that possible?
EDIT:
After doing the console log:
Console.WriteLine($"Time: {DateTime.Now.ToString("HH:mm:ss.fff")}");
I've noticed that 1 second interval actually gets incremented by more than one second (about 1,02 each iteration) so after 50 iterations one second is skipped. I have solved my problem by making timer run each 800ms instead. Not ideal solution, but it works, and second never gets skipped (and I have no problem in triggering the same second twice).
stateTimer = new Timer(someCallback, null, 0, 800);
No that is not possible. That would require you to exactly know when the CPU thinks it is a good idea to start to execute your timer code. Even if you would Thread.Sleep for the remaining time, it would still not mean the code is executed at the very millisecond you want to.
Instead, if you just want to do this for formatting, you can use a custom date/time format to do that.
I had to do something similar in a program that displayed the time and displayed the number of minutes and seconds until the user could do something.
The original code used a 1000 ms timer. This had the problems described by the original poster. I created a thread. The thread had a loop:
private ManualResetEvent myThreadRequestExit = new ManualResetEvent(false);
while (!myThreadRequestExit.WaitOne(1000 - DateTime.UtcNow.Millisecond))
{
// Do the one-second work here
}
The loop will exit and the thread will terminate when MyThreadRequestExit is set.
Although it may fire a few milliseconds after the start of the second it is close enough that the user perceives the timer as ticking when it should and it does not lose seconds as long as the work can be done in less than a second.
Just add this line before you start your timer. Sweet and simple :)
Thread.Sleep(1000 - DateTime.Now.Millisecond);
I have a multithreaded (using a threadpool) C# program that reads from a text file containing logs and batch inserts them into a MongoDB collection. I want a consistent and precise way to measure how long it takes to insert the whole file into the collection.
I can't really call a thread.join (because it's a threadpool), and I can't use a stopwatch because they're running on separate threads.
What's the next best thing?
The current way I'm doing it is the timer on my smartphone. I repeatedly call db.collection.stats() and wait till the count is the same as the number of logs in the file...
If you're using C# 4.0+, I'd recommend you use the CountdownEvent class. Using that class, you can just create an instance with the number of logs for example as the counter:
var countdown = new CountdownEvent(numberOfLogs);
Then, each time you complete a write to MongoDB, you signal from the worker thread:
countdown.Signal(); // decrement counter
And then, in your main process (or another thread):
countdown.Wait(); // returns when the count is zero
// All writes complete
With mongostat (command line tool) you see exactly what goes on in the MongoDB server. It will give you inserts/queries etc per second. It won't automatically stop when it's done inserting, but it will definitely give you an insight to performance. The "inserts" will drop to 0 once you're done importing.
What I want to accomplish it the following thing:
I have a lot of "checks(if/else if etc)" inside a timer, that his interval is 1000 ms,
there is a text file that getting updated and the timer read it every 1000 ms and check for some specific changes,
under 1 of those conditions if it is true the timer, i need to wait 10 sec and then read another text file and then continue with the rest of the timer code.
but in the mean time the timer keep running under those 10 sec and preform the checks every 1sec for all the other conditions and this 1 also.
what i thought to do it
if the conditions i wanted it true i will start a new timer with 10sec interval and it will continue with the code of that specific part.
but what i have hard time to accomplish is how to pass parameters into that timer
such as
newTimer.Start(int "parameter", string "parameter b", list<string> parameters c")
etc etc
or if you got any other idea i will be glad to hear.
To pass parameters, you can always use Tuple.
newTimer.Start(Tuple.Create(param1, param2, param3));
You might not need to have two timer if you do the logic correctly.
Timer *run every second*
Check file
If file has flag Then save in variable the current date + 10 seconds
If current date > saved date Then Check the other file
You need to consider that a System.Windows.Forms.Timer will run on the GUI thread (the thread that run the containing form's message loop / pump), as it uses window messages (WM_TIMER) that are processed by the GUI thread. Because of that, any code that runs under any System.Windows.Forms.Timer in your form will execute synchronously. So, if your start a new System.Windows.Forms.Timer which blocks for 10 seconds, all your other timers will be blocked as well (since the message loop is blocked).
Consider using a System.Threading.Timer or System.Timers.Timer, as they run the timer callback on a different thread. This way, your code will run pretty much as you'd want - every one second the method will be running, regardless of weather the previous call completed or is still blocking (waiting 10 seconds).
My system generates events with integer number. Totally there are about 10 000 of events from 1 to 10 000. Every time I receive new event with numer i need to check how many times I've already received event with such number in tha last second:
if I have received this event more than ~3-10 times in last second than I need to ignore it
otherwise i need to process it.
So I just need to control and ignore "flood" with events with the same number.
There are two requirements:
overhead of the flood control should be really MINIMAL as it used in HFT trading
at the same time i do not need to control "exactly" I just need "roughly" flood control. I.e. it's ok to stop receive events somewhere between 3 and 10 events per second.
So my proposal would be:
create int[10 000] array
every second refresh all items in this array to 0 (refresh operation of item of the array is atomic, also we can iterate over array without any problems and without locking because we do not insert or delete items, however probably someone can recomend special function to "zero" array, take into accout that I can read array at the same time from another thread)
every time new event received we a) Interlocked.Increment corresponding item in the array and only if the result is less than a threshold (~3) we will process it.
So flood control would be just one Intrerlocked.Increment operation and one comparision operation.
What do you tnink can you recommend something better?
One problem with your approach - is that if you clear the counters every second - it might be that you had a flood right before the end of the second but since you've just cleared it you will continue accepting new event.
It might be OK for you as you are good with approximation only.
Another approach may be to have an array of queues of time stamps.
When a new event comes in - you get the relevant queue from the array and clear from its head all the timestamps that occurred more than a second in the past.
The you check the size of the queue, if it is bigger than the threshold you do nothing - otherwise you enter the new event timestamp into the queue and process it.
I realize that this approach might be slower than just incrementing integers but it will be more accurate.
I suppose you can run some benchmarks and find out how slower is it and whether it fits your needs or not.
I'm investigating the Parallelism Break in a For loop.
After reading this and this I still have a question:
I'd expect this code :
Parallel.For(0, 10, (i,state) =>
{
Console.WriteLine(i); if (i == 5) state.Break();
}
To yield at most 6 numbers (0..6).
not only he is not doing it but have different result length :
02351486
013542
0135642
Very annoying. (where the hell is Break() {after 5} here ??)
So I looked at msdn
Break may be used to communicate to the loop that no other iterations after the current iteration need be run.
If Break is called from the 100th iteration of a for loop iterating in
parallel from 0 to 1000, all iterations less than 100 should still be
run, but the iterations from 101 through to 1000 are not necessary.
Quesion #1 :
Which iterations ? the overall iteration counter ? or per thread ? I'm pretty sure it is per thread. please approve.
Question #2 :
Lets assume we are using Parallel + range partition (due to no cpu cost change between elements) so it divides the data among threads . So if we have 4 cores (and perfect divisions among them):
core #1 got 0..250
core #2 got 251..500
core #3 got 501..750
core #4 got 751..1000
so the thread in core #1 will meet value=100 sometime and will break.
this will be his iteration number 100 .
But the thread in core #4 got more quanta and he is on 900 now. he is way beyond his 100'th iteration.
He doesnt have index less 100 to be stopped !! - so he will show them all.
Am I right ? is that is the reason why I get more than 5 elements in my example ?
Question #3 :
How cn I truly break when (i == 5) ?
p.s.
I mean , come on ! when I do Break() , I want things the loop to stop.
excactly as I do in regular For loop.
To yield at most 6 numbers (0..6).
The problem is that this won't yield at most 6 numbers.
What happens is, when you hit a loop with an index of 5, you send the "break" request. Break() will cause the loop to no longer process any values >5, but process all values <5.
However, any values greater than 5 which were already started will still get processed. Since the various indices are running in parallel, they're no longer ordered, so you get various runs where some values >5 (such as 8 in your example) are still being executed.
Which iterations ? the overall iteration counter ? or per thread ? I'm pretty sure it is per thread. please approve.
This is the index being passed into Parallel.For. Break() won't prevent items from being processed, but provides a guarantee that all items up to 100 get processed, but items above 100 may or may not get processed.
Am I right ? is that is the reason why I get more than 5 elements in my example ?
Yes. If you use a partitioner like you've shown, as soon as you call Break(), items beyond the one where you break will no longer get scheduled. However, items (which is the entire partition) already scheduled will get processed fully. In your example, this means you're likely to always process all 1000 items.
How can I truly break when (i == 5) ?
You are - but when you run in Parallel, things change. What is the actual goal here? If you only want to process the first 6 items (0-5), you should restrict the items before you loop through them via a LINQ query or similar. You can then process the 6 items in Parallel.For or Parallel.ForEach without a Break() and without worry.
I mean , come on ! when I do Break() , I want things the loop to stop. excactly as I do in regular For loop.
You should use Stop() instead of Break() if you want things to stop as quickly as possible. This will not prevent items already running from stopping, but will no longer schedule any items (including ones at lower indices or earlier in the enumeration than your current position).
If Break is called from the 100th iteration of a for loop iterating in parallel from 0 to 1000
The 100th iteration of the loop is not necessarily (in fact probably not) the one with the index 99.
Your threads can and will run in an indeterminent order. When the .Break() instruction is encountered, no further loop iterations will be started. Exactly when that happens depends on the specifics of thread scheduling for a particular run.
I strongly recommend reading
Patterns of Parallel Programming
(free PDF from Microsoft)
to understand the design decisions and design tradeoffs that went into the TPL.
Which iterations ? the overall iteration counter ? or per thread ?
Off all the iterations scheduled (or yet to be scheduled).
Remember the delegate may be run out of order, there is no guarantee that iteration i == 5 will be the sixth to execute, rather this is unlikely to be the case except in rare cases.
Q2: Am I right ?
No, the scheduling is not so simplistic. Rather all the tasks are queued up and then the queue is processed. But the threads each use their own queue until it is empty when they steal from other the threads. This leads no way to predict which thread will process what delegate.
If the delegates are sufficiently trivial it might all be processed on the original calling thread (no other thread gets a chance to steal work).
Q3: How cn I truly break when (i == 5) ?
Don't use concurrently if you want linear (in specific) processing.
The Break method is there to support speculative execution: try various ways and stop as soon as any one completes.