Abhishek Gupta
Abhishek Gupta

Reputation: 71

How to calculate time taken by all threads

I am using Following .NET Code

 Class MonitorSample
  Shared Sub RunMonitor()
    Dim o As New Object()
    For i As Integer = 0 To 99
    ThreadPool.QueueUserWorkItem(Function()
       Try
       Monitor.Enter(o)
       Console.WriteLine("Thread {0} acquired lock...working", Thread.CurrentThread.ManagedThreadId)
       Console.WriteLine("Thread {0} performing some I/O operation so yielding the lock temporarily...", Thread.CurrentThread.ManagedThreadId)
       Monitor.PulseAll(o)
       Monitor.Wait(o)
       Console.WriteLine("Thread {0} reacquired lock", Thread.CurrentThread.ManagedThreadId)
       Finally
       Console.WriteLine("Thread {0} released lock", Thread.CurrentThread.ManagedThreadId)
       Monitor.PulseAll(o)
       Monitor.Exit(o)
       End Try
     Return Nothing
   End Function
  )
  Next
  Console.ReadLine()
 End Sub
 Shared Sub Main()
 Dim stopwatch As New Stopwatch()
   stopwatch.Start()
   RunMonitor()
   stopwatch.Stop()
   Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed)
 End Sub
End Class

In the main method is this the right method to calculate time consuemd by thread or we should calculate in some otherway.

Actually the step to print time consumed get printed first while threads get executed later.

Upvotes: 1

Views: 423

Answers (1)

StuartLC
StuartLC

Reputation: 107277

Your Sub won't do as you want - there are 2 issues here

  1. There is a Console.Readline which will also wait for the user's input inside the StopWatch
  2. You aren't synchronizing your threads properly - fortunately, the threads usually finish while waiting for user input, but this won't allow you to time the threads.

The following should fix this by moving the stopwatch tightly around the threads, and also providing a CountDownEvent to allow each thread to indicate when it has completed.

    Shared Sub RunMonitor()
        Dim stopwatch As New Stopwatch()
        stopwatch.Start()
        Dim o As New Object()
        Const numThreads As Integer = 10
        ' Create an Event which signals when we are finished
        Dim allDoneEvent As New CountdownEvent(numThreads)
        For i As Integer = 0 To numThreads - 1
            ThreadPool.QueueUserWorkItem(Function()
                                             Try
                                                 Monitor.Enter(o)
                                                 Console.WriteLine("Thread {0} acquired lock...working", Thread.CurrentThread.ManagedThreadId)
                                                 Console.WriteLine("Thread {0} performing some I/O operation so yielding the lock temporarily...", Thread.CurrentThread.ManagedThreadId)
                                                 Monitor.PulseAll(o)
                                                 Monitor.Wait(o)
                                                 Console.WriteLine("Thread {0} reacquired lock", Thread.CurrentThread.ManagedThreadId)
                                             Finally
                                                 Console.WriteLine("Thread {0} released lock", Thread.CurrentThread.ManagedThreadId)
                                                 Monitor.PulseAll(o)
                                                 Monitor.Exit(o)
                                                 ' This thread indicates that it has finished its work
                                                 allDoneEvent.Signal()
                                             End Try
                                             Return Nothing
                                         End Function
          )
        Next
        ' Wait for all events to finish, or after a timeout
        allDoneEvent.Wait(10000)
        ' Stop the stopwatch before the readline
        stopwatch.Stop()
        Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed)
        Console.ReadLine()
    End Sub

Upvotes: 1

Related Questions