相关疑难解决方法(0)

引用赋值是原子的,为什么需要Interlocked.Exchange(ref Object,Object)?

在我的多线程ASMX web服务,我有我自己的类型SystemData的类别字段_allData它由数List<T>Dictionary<T>标记为volatile.系统data(_allData)会偶尔刷新一次,我会通过创建另一个被调用的对象newData并用新数据填充它的数据结构来实现.当它完成后我就分配了

private static volatile SystemData _allData

public static bool LoadAllSystemData()
{
    SystemData newData = new SystemData();
    /* fill newData with up-to-date data*/
     ...
    _allData = newData.
} 
Run Code Online (Sandbox Code Playgroud)

这应该工作,因为赋值是原子的,并且具有对旧数据的引用的线程继续使用它,而其余的在分配之后具有新的系统数据.然而,我的同事说,volatile我应该使用,而不是使用关键字和简单的InterLocked.Exchange分配,因为他说在某些平台上,不能保证引用赋值是原子的.另外:当我宣布the _allData字段volatile

Interlocked.Exchange<SystemData>(ref _allData, newData); 
Run Code Online (Sandbox Code Playgroud)

产生警告"对易变场的引用不会被视为不稳定的"我应该怎么看待这个?

c# multithreading atomicity volatility

104
推荐指数
4
解决办法
3万
查看次数

在英特尔架构上双读原子?

我的同事和我正在讨论使用C#.NET 4.0在英特尔架构上读取双精度的原子性.他认为我们应该使用Interlocked.Exchange方法写入a double,但只是读取double值(在其他一些线程中)保证是原子的.我的论点是.NET不保证这种原子性,但他的论点是在英特尔架构上这是有保证的(可能不在AMD,SPARC等).

任何英特尔和.NET专家都会分享一些亮点吗?

Reader可以读取陈旧(前一个)值,但不能读取不正确的值(写入前后的部分读取给出垃圾值).

.net c# intel

29
推荐指数
3
解决办法
3486
查看次数

如何轻松使这个计数器属性线程安全?

我在类中有属性定义,我只有计数器,这必须是线程安全的,这不是因为get并且set不在同一个锁中,如何做到这一点?

    private int _DoneCounter;
    public int DoneCounter
    {
        get
        {
            return _DoneCounter;
        }
        set
        {
            lock (sync)
            {
                _DoneCounter = value;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

c# thread-safety

11
推荐指数
2
解决办法
1万
查看次数

volatile DateTime

由于DateTime不能声明为volatile,这是对的吗?:

        private DateTime _time;
        public DateTime Time
        {
            get
            {
                Thread.MemoryBarrier();
                return _time;
            }
            set
            {
                _time = value;
                Thread.MemoryBarrier();
            }
        }
Run Code Online (Sandbox Code Playgroud)

该属性可以从不同的线程访问,所以我想确保它们始终获得最新版本,而不使用争用(锁定).

编辑:

  • 我有一组难以创建的项目,每个项目都有一个名为CreationTime的DateTime属性,指示何时创建此项目.它被初始化为DateTime.UtcNow.
  • 每次访问项目时,该属性都会更新为DateTime.UtcNow.
  • 有一个线程,在线程计时器中及时执行,检查是否(DateTime.UtcNow + 1小时)> item.CreationTime,如果为true则删除该项.

我想确保当"删除线程"进入集合时,所有项目都有最新的"最后访问"DateTime,因此我可以避免再次创建项目,因为缓存保持该值几毫秒:d

提前致谢.

.net c# multithreading synchronization volatile

10
推荐指数
1
解决办法
6007
查看次数

为什么DateTime.Now需要是线程安全的?

我正在阅读Joe的Albahari C#线程教程:

作者解释了为什么DateTime.Now需要线程安全:

只有当所有并发线程都知道并使用锁定时,才能对自定义锁定周围的对象进行包装访问.如果对象的范围很广,则可能不是这种情况.最糟糕的情况是公共类型的静态成员.例如,假设DateTime结构上的静态属性DateTime.Now不是线程安全的,并且两个并发调用可能导致输出乱码或异常.使用外部锁定解决此问题的唯一方法可能是在调用DateTime.Now之前锁定类型本身 - lock(typeof(DateTime)).只有当所有程序员都同意这样做时(这是不可能的),这才有效.此外,锁定类型会产生其自身的问题.

因此,DateTime结构上的静态成员已经过仔细编程,以确保线程安全.

根据MS docs,.NOWpublic static DateTime Now { get; },即只读属性.如果它是只读的,为什么要打扰线程安全呢?两个并发呼叫应该能够获得当前时间而不会相互干扰?

编辑:很多人指出问题不是很清楚.我确实假设它应该是安全的,因为:它是只读的,因为它是时间(总是在改变).

.net c# multithreading

10
推荐指数
2
解决办法
3814
查看次数

C#中的++运算是原子的吗?

我有多个线程使用"++"或" - "操作访问单个Int32变量.

我们是否需要在访问之前锁定,如下所示?

    lock (idleAgentsLock)
    {
       idleAgents--;  //we should place it here.
    }
Run Code Online (Sandbox Code Playgroud)

或者如果我不进行锁定会有什么后果?

.net c#

5
推荐指数
2
解决办法
506
查看次数

Array.Copy是否保持每个元素的原子读写保证?

C#确保某些类型始终具有原子读取和写入.在调用Array.Copy这两种类型的数组时,我是否有同样的保证?每个元素是否以原子方式读写?我浏览了一些源代码,但没有得到一个可靠的答案.

例如,如果我推出自己的代码来复制两个数组......

static void Copy<T>(T[] source, T[] destination, int length)
{
    for (int i = 0; i < length; ++i)
        destination[i] = source[i];
}
Run Code Online (Sandbox Code Playgroud)

...并且调用了Copy<int>变体,这保证了每个元素都是从原子上读取source并原子写入的,destination因为C#承诺int读取和写入都是原子的.我只是问是否Array.Copy保持这种保证(相反,使用它自己的专用内存块复制例程,可能会破坏这种保证).

.net c# atomic

5
推荐指数
1
解决办法
230
查看次数

在C#中,"原子"是什么意思?

我在C#6.0和.NET 4.6框架中读到了这个:

"赋值和简单算术运算不是原子的".

那么,它究竟意味着什么?

c#

4
推荐指数
2
解决办法
6356
查看次数

为什么Datetime对象不能在c#中出现波动?

我可以想到一些使用案例,让DateTime对象成为原子非常有用.从语言设计的角度来看,有什么优势可以使DateTime不稳定?

c# datetime volatile

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

线程安全阅读Guid Twice

我正在读一个Guid对象两次,一次是在if语句中,一次是在if语句的块中.

在CI中,将在本地复制变量,以确保if语句中的读取操作不会读取不同的值(如果另一个线程在中间更改此值).

我怀疑以下方法是a)线程安全和b)会给我相同的值:

public class MyClass {

private Guid MyProp {get;set;} = Guid.Empty; //May be changed at will

public OnRunLoop() //Gets called periodicaly on a thread
{

    var ALocalCopyOfTheProp = MyProp; //Copy locally
    if(ALocalCopyOfTheProp == AValueFromAnotherPlace) //Read 1
    {
        ...

        var AnotherReadOfTheVariable = ALocalCopyOfTheProp; //Read 2

    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

C#.NET本身没有谷歌搜索的复制功能,所以在这种情况下最佳做法是什么?

编辑: - 请注意,在这种情况下,MyProp不在我的手中.我不能使用锁,因为该物业来自其他地方.(道歉没有让它更清晰) - Guid是一个结构而不是引用类型

.net c# guid

-3
推荐指数
1
解决办法
211
查看次数