相关疑难解决方法(0)

如何正确读取Interlocked.Increment'ed int字段?

假设我有一个非易失性的int字段,以及一个它Interlocked.Increment的线程.另一个线程可以直接安全地读取它,还是读取也需要互锁?

我以前认为我必须使用互锁读取来保证我看到当前值,因为毕竟,该字段不是易失性的.我一直在Interlocked.CompareExchange(int, 0, 0)努力实现这一目标.

但是,我偶然发现了这个答案,这表明实际的普通读取总会看到Interlocked.Incremented值的当前版本,并且因为int读取已经是原子的,所以不需要做任何特殊的事情.我还发现了Microsoft拒绝Interlocked.Read(ref int)请求的请求,进一步表明这完全是多余的.

那么我能真正安全地阅读这样一个int领域的最新价值Interlocked吗?

.net c# multithreading thread-safety

56
推荐指数
4
解决办法
1万
查看次数

"对易变场的引用不会被视为不稳定的"含义

以下代码

using System.Threading;

class Test
{
    volatile int counter = 0;
    public void Increment()
    {
        Interlocked.Increment(ref counter);
    }
}
Run Code Online (Sandbox Code Playgroud)

引发以下编译器警告:

"A reference to a volatile field will not be treated as volatile"
Run Code Online (Sandbox Code Playgroud)

我在这里做错了什么来提出这个警告?为什么编译器会对此发出警告?

.net c# multithreading volatile

42
推荐指数
3
解决办法
8607
查看次数

延迟初始化对象的线程安全处置

在 C# 中处理延迟初始化对象的线程安全方法是什么?假设我有以下Lazy构造:

Lazy<MyClass> lazy = new Lazy<MyClass>(() => MyClass.Create(), true);
Run Code Online (Sandbox Code Playgroud)

稍后,我可能想处置MyClass创建的实例。大多数现有的解决方案都推荐这样的内容:

if (lazy.IsValueCreated)
{
    lazy.Value.Dispose();
}
Run Code Online (Sandbox Code Playgroud)

但据我所知,IsValueCreated没有任何锁:https://referencesource.microsoft.com/#mscorlib/system/Lazy.cs,284

MyClass这意味着当我们检查 时,另一个线程可能正在初始化过程中IsValueCreated。在这种情况下,我们将观察IsValueCreated到错误,并最终泄漏资源。这里正确的做法是什么?还是我错过了一些微妙的细节?

.net c# thread-safety

8
推荐指数
1
解决办法
4348
查看次数

标签 统计

.net ×3

c# ×3

multithreading ×2

thread-safety ×2

volatile ×1