这个问题不是关于竞争条件,原子性,或者为什么要在代码中使用锁.我已经知道了.
更新:我的问题不是"存在易失性存储器的奇怪现象"(我知道它确实存在),我的问题是"没有.NET运行时抽象,所以你永远不会看到它".
请参阅http://www.yoda.arachsys.com/csharp/threads/volatility.shtml 和关于字符串属性本身线程安全的第一个答案吗?
(它们实际上是同一篇文章,因为一个引用另一个.)一个线程设置bool而另一个线程循环永远读取bool - 那些文章声称读取线程可能缓存旧值并且从不读取新值,所以因此你需要一个锁(或使用volatile关键字).他们声称以下代码可能永远循环.现在我同意锁定变量是一种好习惯,但我无法相信.NET运行时会真正忽略内存值的变化,如文章所述.我理解他们关于易失性内存与非易失性内存的讨论,我同意他们在非托管中有一个有效的观点代码,但我无法相信.NET运行时将无法正确地抽象出来,以便下面的代码能够满足您的期望.这篇文章甚至承认代码"几乎可以肯定"有效(虽然不能保证),所以我就索赔要求BS.任何人都可以验证以下代码是否真的有效?是否有人能够得到一个案例(也许你不能总是重现它)这个失败的地方?
class BackgroundTaskDemo
{
private bool stopping = false;
static void Main()
{
BackgroundTaskDemo demo = new BackgroundTaskDemo();
new Thread(demo.DoWork).Start();
Thread.Sleep(5000);
demo.stopping = true;
}
static void DoWork()
{
while (!stopping)
{
// Do something here
}
}
}
Run Code Online (Sandbox Code Playgroud) 我希望这不是一个愚蠢的问题:我刚刚开始使用MVVM灯(到目前为止爱它!).在"之前的时间"(即在使用MVVML之前),我不得不发送任何代码,这些代码会触及在其中引发INotifyPropertyChanged事件的属性设置器.
我(错误地?)认为使用MVVMlight时需求会消失.
我仍然要使用它,对吗?我的实验告诉我一个响亮的是.
这是真正愚蠢的部分 - 因为需要在某处初始化MVVML dispatcherhelper类,我假设它保存了UI线程,为什么不让RaisePropertyChanged调用自动执行Dispatch?这似乎是常见的事情吗?
本身不是批评,更多的是"它怎么不以这种方式工作":-)
编辑 (从作者的评论中复制)
FWIW,我这样做了:
public class QViewModelBase : ViewModelBase {
protected override void RaisePropertyChanged(string propertyName) {
DispatcherHelper.CheckBeginInvokeOnUI( () => base.RaisePropertyChanged(propertyName));
}
protected override void RaisePropertyChanged<T>(string propertyName, T oldValue, T newValue, bool broadcast) {
DispatcherHelper.CheckBeginInvokeOnUI( () => base.RaisePropertyChanged<T>(propertyName, oldValue, newValue, broadcast));
}
}
Run Code Online (Sandbox Code Playgroud)