英文:
Generic Volatile.Read to Thread.VolatileRead conversion
问题
I need to get this code from .NET 4.5+ working on .NET 4.0. The generic Volatile.Read
isn't available in that version. I'm trying to use the Thread.VolatileRead
to get this working. I need to know if this outright a bad idea and if not, what I should test for?
我需要将这段代码从.NET 4.5+转换为在.NET 4.0上运行。通用的 Volatile.Read
在那个版本中不可用。我尝试使用 Thread.VolatileRead
来使其工作。我需要知道这是不是一个坏主意,如果不是,我应该进行什么测试?
See what I replaced in the commented line.
查看我在注释行中替换的部分。
internal static TValue EnsureSingletonInitialized<TValue, TArg>(ref TValue value, TArg arg, Func<TArg, TValue> initialize) where TValue : class
{
//TValue currentValue = Volatile.Read(ref value);
object o = value;
TValue currentValue = (TValue)Thread.VolatileRead(ref o);
if (null != currentValue)
return currentValue;
TValue candidateValue = initialize(arg);
return Interlocked.CompareExchange(ref value, candidateValue, null) ?? candidateValue;
}
英文:
I need to get this code from .NET 4.5+ working on .NET 4.0. The generic Volatile.Read
isn't available in that version. I'm trying to use the Thread.VolatileRead
to get this working. I need to know if this outright a bad idea and if not, what I should test for?
See what I replaced in the commented line.
internal static TValue EnsureSingletonInitialized<TValue, TArg>(ref TValue value,
TArg arg, Func<TArg, TValue> initialize)
where TValue : class
{
//TValue currentValue = Volatile.Read(ref value);
object o = value;
TValue currentValue = (TValue)Thread.VolatileRead(ref o);
if (null != currentValue)
return currentValue;
TValue candidateValue = initialize(arg);
return Interlocked.CompareExchange(ref value, candidateValue, null) ?? candidateValue;
}
答案1
得分: 1
以下是已翻译的代码部分:
最安全的实现缺失的 `Read<T>`/`Write<T>` 方法可能如下:
public static class VolatileEx
{
public static T Read<T>(ref T location) where T : class
{
return Interlocked.CompareExchange(ref location, null, null);
}
public static void Write<T>(ref T location, T value) where T : class
{
Interlocked.Exchange(ref location, value);
}
}
使用 Interlocked
确保 Read
/Write
操作是原子的,并且前后的指令不会被重新排序。Interlocked
APIs 强制实施完整的内存屏障,因此它们比强制实施半屏障的 Volatile
APIs 更昂贵。但由于您降级到较旧的 .NET 平台,可能会损失一些性能。
源代码:
Thread.VolatileRead
(.NET Framework)Volatile.Read
(.NET 7)
<details>
<summary>英文:</summary>
The safest implementations of the missing `Read<T>`/`Write<T>` methods are probably these:
public static class VolatileEx
{
public static T Read<T>(ref T location) where T : class
{
return Interlocked.CompareExchange(ref location, null, null);
}
public static void Write<T>(ref T location, T value) where T : class
{
Interlocked.Exchange(ref location, value);
}
}
Using the [`Interlocked`][1] ensures that the `Read`/`Write` are atomic, and also that the preceding/following instructions will not be reordered. The `Interlocked` APIs impose full memory barriers, so they are more expensive than the [`Volatile`][2] APIs that impose half fences. But since you downgraded to an older .NET platform, losing some performance is to be expected.
Source code:
- [`Thread.VolatileRead`][3] (.NET Framework)
- [`Volatile.Read`][4] (.NET 7)
[1]: https://learn.microsoft.com/en-us/dotnet/api/system.threading.interlocked
[2]: https://learn.microsoft.com/en-us/dotnet/api/system.threading.volatile
[3]: https://referencesource.microsoft.com/#mscorlib/system/threading/thread.cs,1684
[4]: https://github.com/dotnet/runtime/blob/0656c910d9384a2628549f034f0d111caa2e1da3/src/libraries/System.Private.CoreLib/src/System/Threading/Volatile.cs#L221
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论