Understanding CLR 2.0 Memory Model

倖福魔咒の 提交于 2019-12-02 18:27:25

Joe Duffy discusses Rule 5 on pp517-18 of Concurrent Programming on Windows:

As an example of when a load might be introduced, consider this code:

MyObject mo = ...;
int f = mo.field;
if (f == 0)
{
    // do something
    Console.WriteLine(f);
}

If the period of time between the initial read of mo.field into variable f and the subsequent use of f in the Console.WriteLine was long enough, a compiler may decide it would be more efficient to reread mo.field twice. ... Doing this would be a problem if mo is a heap object and threads are writing concurrently to mo.field. The if-block may contain code that assumes the value read into f remained 0, and the introduction of reads could break this assumption. In addition to prohibiting this for volatile variables, the .NET memory model prohibits it for ordinary variables referring to GC heap memory too.

I blogged about one important place where this matters: the standard pattern for raising an event.

EventHandler handler = MyEvent;
if (handler != null)
    handler(this, EventArgs.Empty);

In order to prevent problems with removing an event handler on a separate thread, we read the current value of MyEvent and only invoke the event handlers if that delegate is non-null.

If reads from the heap could be introduced, the compiler/JIT might decide that it could be better to read MyEvent again, rather than using the local, which would introduce a race condition.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!