4

好的,所以我有一个相当简单的问题,我找不到简明的答案。我想知道lock()在读取Stopwatch它仍在运行的一段时间的 elapsed 属性时是否需要担心调用语句。

也是Stopwatch我应该用来测量线程运行时间的东西。我读过其他类似的问题 aDispatchTimer可以使用。我也研究过使用事件,但是对于如此简单的事情来说似乎有很多开销,请告诉我这是否完全错误并且我应该使用事件。一些简单的代码来说明我在说什么。

 class foo
 {
      private bool _isRunning { get; set; }
      private Stopwatch sw { get; set; }
      public void StartThread()
      {
          this._isRunning = true;
          new Thread(new ThreadStart(this.DoWork)).Start();
          this.sw.Restart();
      }     
      public void StopThread()
      {
          this._isRunning = false;
          this.sw.Stop();
      }
      private void DoWork()
      {
          while(this._isRunning)
          {
               //Do Stuff
          }
      }
      public TimeSpan GetRuntime()
      {
          return this.sw.Elapsed;
      }
      public foo()
      {
          _isRunning = false;
          sw = new Stopwatch();
      }
 }

假设在使用上述类的应用程序中,我将GetRuntime()在停止之前从不同的线程调用Stopwatch我是否需要添加一条lock()语句以确保我获得正确的数据,并且我不会阻止Stopwatch继续运行。或者我是否正确地认为它不需要 alock()并且会很好。

我确实理解理论上您可以根据需要运行尽可能多的读取,我只是好奇地看到 Elapsed 属性后备存储是否会不断被写入是否改变了事情。我已经阅读了很多关于线程安全的信息,但我只是在寻找一个澄清和确认我确实在正确地考虑这个问题。

4

1 回答 1

5

MSDN 文档指出,关于秒表,“不保证任何实例成员都是线程安全的。” 请注意,这里肯定存在理论上的漏洞,因为它在内部使用“长”滴答计数,并且在 32 位处理器上更新 long 不是原子操作。您可能会看到部分更新(因此损坏)的值。您可能不会注意到,直到 Ticks 恰好超过 32 位边界,此时您可能会遇到一个非常意外的罕见错误(您可能会读取 Int32.MaxValue,然后是 0,然后是 Int32.MaxValue + 1,如果您在错误的时刻查询它,则会在经过的时间上产生非常大的差异。)

于 2013-05-09T17:53:31.277 回答