Reputation: 379
I have this piece of code that spawns 6 threads and executes the GetAverage
method simultaneously on each thread.
var threadFinishEvents = new List<EventWaitHandle>();
//StopWatch sw = new StopWatch();
for (int i = 0; i < 6; i++)
{
var threadFinish = new EventWaitHandle(false, EventResetMode.ManualReset);
threadFinishEvents.Add(threadFinish);
var thread = new Thread(delegate()
{
GetAverage(userName);
threadFinish.Set();
//sw.Stop();
});
//sw.Start();
thread.Start();
}
Mutex.WaitAll(threadFinishEvents.ToArray(), threadTimeout);
long timeElapsed = sw.TimeElapsed();
I want to record the time taken by each thread to execute and log it to a database. I read a lot of posts on google that suggested using Stopwatch
. I have tried adding the Stopwatch
code (which I have commented out) to the snippet but not sure if this is right. Can someone help me please?
Upvotes: 0
Views: 885
Reputation: 22008
There are 2 possibilities to measure average time: measure total time and divide it by number or threads or measure each thread time, sum it and divide by number (but in this case you can have so called moving average, which will be available before last thread time is obtained). Which one to use - depends.
var watch = new StopWatch();
watch.Start();
// .. whole job, creating N threads, waiting for all of them to finish
watch.Stop();
var result = watch.Elapsed / N;
It will include overhead (a loop time, creating thread, execution of the first thread, etc), but will be more and more accurate the more threads you run.
// inside each thread
var watch = new StopWatch();
watch.Start();
// ... thread job
watch.Stop();
timeX = watch.Elapsed;
// after job is done
Mutex.Wait...
result = (time1 + time2 + ... ) / N;
You don't include any overhead, most accurate result. But you have to keep all timeX
.
// inside each thread
var watch = new StopWatch();
watch.Start();
// ... thread job
watch.Stop();
result = (_timePrevious + watch.Elapsed) / 2;
_timePrevious = watch.Elapsed;
// after job done
result = result; // total result is the same as the most recent
Here we use only 2 measurements (and first value of result
will be inaccurate, due to uninitialized _timePrevious
) , but it could be more. You can have a dynamic list to hold all times (which makes result most accurate at the end), or, to example, fixed array with moving position (which gets filled by first measurement, but then is updated by new threads).
Upvotes: 0
Reputation: 172468
If you want the total time, start the stopwatch before the loop and stop it after the WaitAll
.
If you need separate measurements for each thread, create a separate stopwatch for each thread inside the loop. Put sw.Start()
at the beginning of your delegate and sw.Stop()
at the end of the delegate. Put the stopwatches in a List (as you do with the EventWaitHandle) and read the TimeElapsed
values at the end of your code.
Upvotes: 1