1

我正在使用以下 .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

在 main 方法中,这是计算线程消耗时间的正确方法,或者我们应该以其他方式计算。

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

4

1 回答 1

1

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

  1. 有一个Console.Readlinewhich 也将在 StopWatch 内等待用户的输入
  2. 您没有正确同步线程 - 幸运的是,线程通常在等待用户输入时完成,但这不允许您为线程计时。

下面应该通过在线程周围紧密移动秒表来解决此问题,并提供一个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
于 2012-09-05T10:32:17.330 回答