Вопрос может быть интерпретирован двумя способами:
1) Является ли BackgroundWorker.CancellationPending реализация правильной?
Это не правильно, потому что это может привести к тому, что запрос на отмену будетнезамеченной.Реализация использует обычное чтение из поля поддержки.Если это вспомогательное поле обновляется другими потоками, тогда обновление может быть невидимым для кода чтения.Вот как выглядит реализация:
// non volatile variable:
private Boolean cancellationPending;
public Boolean CancellationPending {
get {
// ordinary read:
return cancellationPending;
}
}
Правильная реализация будет пытаться прочитать наиболее актуальное значение.Это может быть достигнуто путем объявления резервного поля «volatile», используя барьер памяти или блокировку.Возможно, есть и другие варианты, и некоторые из них лучше, чем другие, но зависит от команды, владеющей классом BackgroundWorker.
2) Является ли код, который использует BackgroundWorker.CancellationPending, правильным?
while (!backgroundWorker.CancellationPending) {
DoSomething();
}
Этот код правильный.Цикл будет вращаться до тех пор, пока CancellationPending не вернет значение true.Помните, что свойства C # - это просто синтаксический сахар для методов CLR.На уровне IL это просто еще один метод, который будет выглядеть как «get_CancellationPending».Возвращаемые значения метода не кэшируются вызывающим кодом (возможно, потому что слишком сложно определить, есть ли у метода побочные эффекты).