我在不确定是否有必要的地方使用了 volatile。我很确定在我的情况下锁会是矫枉过正。阅读此线程(Eric Lippert 评论)让我对 volatile 的使用感到焦虑:何时应在 c# 中使用 volatile 关键字?
我使用 volatile 是因为我的变量在多线程上下文中使用,在该上下文中可以同时访问/修改该变量,但是我可以在没有任何伤害的情况下松散添加(参见代码)。
我添加了“易失性”以确保不会发生未对齐的情况:仅读取变量的 32 位和另一个 fetch 上的其他 32 位,这可以通过在中间从另一个线程写入来打破 2。
我之前的假设(之前的陈述)真的不会发生吗?如果不是,是否仍然需要使用“易失性”(选项属性修改可能发生在任何线程中)。
在阅读了2个第一个答案后。我想坚持这样一个事实,即代码的编写方式,如果由于并发性我们错过了一个增量(想从 2 个线程增加,但结果由于并发性只增加一个),这并不重要,如果至少变量“_actualVersion”递增。
作为参考,这是我使用它的代码部分。它仅在应用程序空闲时报告保存操作(写入磁盘)。
public abstract class OptionsBase : NotifyPropertyChangedBase
{
private string _path;
volatile private int _savedVersion = 0;
volatile private int _actualVersion = 0;
// ******************************************************************
void OptionsBase_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
_actualVersion++;
Application.Current.Dispatcher.BeginInvoke(new Action(InternalSave), DispatcherPriority.ApplicationIdle);
}
// ******************************************************************
private void InternalSave()
{
if (_actualVersion != _savedVersion)
{
_savedVersion = _actualVersion;
Save();
}
}
// ******************************************************************
/// <summary>
/// Save Options
/// </summary>
private void Save()
{
using (XmlTextWriter writer = new XmlTextWriter(_path, null))
{
writer.Formatting = Formatting.Indented;
XmlSerializer x = new XmlSerializer(this.GetType());
x.Serialize(writer, this);
writer.Close();
}
}