确保类是线程安全的,只有属性(任何特定于此的.NET 4.0技术?)

Eve*_*ers 1 .net c# multithreading thread-safety c#-4.0

我有一个有两个属性和两个方法的类.比如下面的例子.(请忽略数据类型或返回类型,这只是一个典型的场景)

// The methods could be invoked by multiple threads
    public class Stock
    { 

    private static int FaceValue {get; set;}
    private static int Percent (get; set;}

    //    method that updates the two properties
    Public void UpdateStock()
    {
      FaceValue += 1;
      Percent = FaceValue * 100;
    }

    //   method that reads the two properties
    public int[] GetStockQuote()
    {
        return new int[] { FaceValue, Percent};
    }

    }
Run Code Online (Sandbox Code Playgroud)

我需要确保这个类是线程安全的.我可以在这两种方法中使用lock(obj)作为一种技术来使其成为线程安全但是考虑到以下因素,最好的技术是使其成为线程安全的:

  1. 只读取/更新了两个属性.因此,不确定锁定方法内是否是一种好方法.

  2. 如果我只是使属性线程安全而不是方法或类是否足够?

  3. 另外,有没有办法使整个类线程安全而不是单独的方法或属性?.Net 4.0的任何推荐的锁定技术?

只是想知道我是否正在考虑这个权利,或者考虑到这些,我可能会使它复杂化.非常感谢提前帮助我明确这一点.

玛尼

Ree*_*sey 6

一般来说,这lock可能是最简单的方法.

一个可能更好的选择是使这个类不可变.如果你这样做,那么一旦创建它就无法改变类中的值,你不必再在读取值时担心,因为它们无法被修改.

在这种情况下,可以通过使用一个带有两个值的构造函数来完成,并且更改UpdateStock为更像:

public Stock GetUpdatedStock()
{
     // Create a new instance here...
     return new Stock(this.FaceValue + DateTime.Now.MilliSecond, this.FaceValue * 100);
}
Run Code Online (Sandbox Code Playgroud)

编辑:

既然您已经使FaceValue和Percent成为静态,那么您将需要同步.A lock可能是最简单的选择.

使用单个值,您可以使用Interlocked类以原子方式处理更新,但是无法对两个值*进行原子更新,这可能是正确完成线程安全所必需的.在这种情况下,通过a同步lock将解决您的问题.

*注意:如果你把两个值都放在一个类中,并且交换了整个类实例,这可能在没有锁定的Interlocked.CompareExchange情况下完成 - 但这可能比它的价值更麻烦.