我有一个变量,我用它来表示状态.它可以从多个线程读取和写入.

我用Interlocked.ExchangeInterlocked.CompareExchange换一下.不过,我是从多个线程阅读它的.

我知道volatile可以用来确保变量不是本地缓存的,而是直接从内存中读取.

但是,如果我将变量设置为volatile,那么它会生成一个关于使用volatile和使用ref传递给联锁方法的警告.

我想确保每个线程都在读取变量的最新值,而不是某个缓存版本,但我不能使用volatile.

有一个Interlocked.Read,但它适用于64位类型,在紧凑型框架上不可用.它的文档中说,32位类型不需要它,因为它们已经在单个操作中执行.

互联网上有一些声明说,如果您对所有访问都使用互锁方法,则不需要易失性.但是,您不能使用互锁方法读取32位变量,因此不可能对所有访问都使用互锁方法.

有没有什么方法可以在不使用锁的情况下实现变量的线程安全读写?

推荐答案

在使用Interlocked.Xxx个函数时,您可以安全地忽略该警告(请参见this question),因为它们总是执行不稳定的操作.所以对于共享状态,volatile变量是完全合适的.如果你想不惜一切代价摆脱这个警告,你实际上需要对Interlocked.CompareExchange (ref counter, 0, 0)进行连锁读取.

Edit:实际上,如果要直接写入状态变量only(即不使用Interlocked.Xxx),则需要volatile.As jerryjvl mentioned,通过联锁(或易失性)操作更新的变量读数将使用最新值.

.net相关问答推荐

在计算Total毫秒时,.NET TimeSpan类中是否存在错误?

如何使用AWS Lambda函数制作网络挂钩?

C#:如何构造异步/等待代码,其中许多请求是针对相同的、返回缓慢的数据发出的,这可以满足所有请求

如何运行大量阻塞/同步 I/O 操作

有没有更好的方法使用 Pusher Channels 的批事件发布消息?

如何在 NET 5 / 6 中使用 Direct3D11CaptureFramePool

Erlang 的让它崩溃的哲学 - 适用于其他地方吗?

.NET - WindowStyle = hidden 与 CreateNoWindow = true?

标签从右向左增长

C# - 获取不包括隐藏文件的文件列表

在 WinForms 应用程序中查找焦点控件的首选方法是什么?

C# 有办法给我一个不可变的字典吗?

C# 中的 myCustomer.GetType() 和 typeof(Customer) 有什么区别?

将属性序列化为元素中的 Xml 属性

如何在 C# 中仅设置 DateTime 变量的时间部分

.NET 的 String.Normalize 有什么作用?

在 .NET 中计算目录大小的最佳方法是什么?

等效于 C# 在 powershell 中的使用关键字?

CryptographicException 未处理:系统找不到指定的文件

Environment.GetFolderPath(...CommonApplicationData) 在 Vista 上仍然返回C:\Documents and Settings\