Просматривая исходный код MEF, я нашел этот кусок. Может кто-нибудь объяснить, почему MemoryBarrier
нужен внутри замка?Почему здесь используется Thread.MemoryBarrier?
Весь метод:
public void SatisfyImportsOnce(ComposablePart part)
{
this.ThrowIfDisposed();
if (this._importEngine == null)
{
ImportEngine importEngine = new ImportEngine(this, this._compositionOptions);
lock(this._lock)
{
if (this._importEngine == null)
{
Thread.MemoryBarrier();
this._importEngine = importEngine;
importEngine = null;
}
}
if(importEngine != null)
{
importEngine.Dispose();
}
}
this._importEngine.SatisfyImportsOnce(part);
}
Это * кажется *, что иногда, замок не хватает –
Это невозможно ответить на этот вопрос, не зная намного больше контекста. –
Это FUD на процессоре со слабой моделью памяти, некоторые программисты Microsoft, вероятно, никогда не оправятся от необходимости приручать Itanium. Это гарантирует, что другой поток может наблюдать полностью построенный объект, когда он использует ссылку _importEngine. На слабом процессоре эта ссылка может быть записана в память до того, как будут записаны поля объекта, чтобы в другом потоке можно было увидеть значение неинициализированного поля. Не обязательно, так как .NET 2.0 и определенно не нужен здесь, поскольку блокировка уже подразумевает барьер памяти. –