user1550951
user1550951

Reputation: 379

Log the time taken by a Thread

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

Answers (2)

Sinatr
Sinatr

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.

Measure total time

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.

Measure each thread time

//  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.

Moving average time

//  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

Heinzi
Heinzi

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

Related Questions