Секундомер истек

Итак, у меня есть довольно простой вопрос, на который я не мог найти краткий ответ. Мне интересно, нужно ли беспокоиться о вызове оператора lock() при чтении искомого свойства Stopwatch, пока он все еще работает.

Также есть 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 постоянно записывается, если это изменило ситуацию или нет. Я прочитал много информации о безопасности потоков, но я просто ищу разъяснения и подтверждения. Я действительно думаю об этом правильно.

1 ответ

документация MSDN указывает, что в отношении секундомера: "Любые члены экземпляра не гарантируются потокобезопасностью". Обратите внимание, что здесь определенно существует теоретическая уязвимость, так как она использует "длинный" счетчик отсчетов внутри и обновление длинных 32-разрядных процессоров не является атомной операцией. Вы можете увидеть частично обновленные (и, следовательно, поврежденные) значения. Вероятно, вы не заметите, пока Ticks не пройдет мимо 32-битной границы, после чего вы можете столкнуться с очень неожиданной редкой ошибкой (вы могли бы прочитать Int32.MaxValue, за которым следует 0, за которым следует Int32.MaxValue + 1, что дает очень большую разницу в прошедшие времена, если вы запросите его в самый неподходящий момент.)

licensed under cc by-sa 3.0 with attribution.