c# - 秒表耗时线程安全

标签 c# .net multithreading thread-safety

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

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

 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从继续运行。或者我认为它不需要 lock() 是否正确?会没事的。

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

最佳答案

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

关于c# - 秒表耗时线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16467934/

相关文章:

.net - 仅使用原子操作的 C++/CLI 中的线程同步

Java - 静态方法的线程安全

c++ - 调用timer_create()的新线程

c# - string[] 计数被传递给 ComboBox,但 string[] 值没有

c# - TreeView 上下文菜单在 HierarchicalDataTemplate 中不起作用

.net - 如何完全卸载 Red Gate 的 .NET Reflector?

c++ - 使用线程递归传递数据

c# - C#中如何获取对象的值

c# - 从数据库表生成类

c# - 在 foreach 循环中修改对象的属性不起作用?