如何计算所有线程所用的时间

时间:2012-09-05 08:57:25

标签: .net vb.net multithreading parallel-processing

我正在使用以下.NET代码

 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

在主方法中,这是通过线程计算时间的正确方法,或者我们应该在其他方面进行计算。

实际上,打印时间的步骤首先打印,而线程稍后执行。

1 个答案:

答案 0 :(得分:1)

您的Sub不会按照您的意愿执行 - 这里有2个问题

  1. 还有Console.Readline等待用户在StopWatch中的输入
  2. 您没有正确地同步线程 - 幸运的是,线程通常在等待用户输入时完成,但这不允许您为线程计时。
  3. 以下内容应通过将秒表紧紧围绕线程移动来解决此问题,并提供CountDownEvent以允许每个线程指示它何时完成。

        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