如何使用 Interlocked.Add 更新我的模型计数器值

How to update my model counter value using Interlocked.Add

所以我有这个模型:

public class Container : INotifyPropertyChanged
{
    private int _total;
    private static InjectionContainer _mainContainer = new InjectionContainer();
    private static InjectionContainer _secondContainer = new InjectionContainer();
    private ObservableCollection<MyData> _files = new ObservableCollection<MyData>();

    public int TotalPackets
    {
        get { return _total; }
        set
        {
            _total = value;
            OnPropertyChanged("Total");
        }
    }

    public ObservableCollection<MyData> List
    {
        get { return _files; }
        set { _files = value; }
    }
}

除此之外 Container class 我想更新我的 class Total 属性 但我需要它是线程安全的因为很多线程同时做:

public static void UpdateTotal(Container container, int value)
{
    Interlocked.Add(ref container.Total, value);
}

并得到这个错误:

A property or indexer may not be passed as an out or ref parameter

您应该在 Container:

中创建一个 Add 方法
public class Container : INotifyPropertyChanged
{
    private int _total;
    private static InjectionContainer _mainContainer = new InjectionContainer();
    private static InjectionContainer _secondContainer = new InjectionContainer();
    private ObservableCollection<MyData> _files = new ObservableCollection<MyData>();

    public int TotalPackets
    {
        get { return _total; }
    }

    public ObservableCollection<MyData> List
    {
        get { return _files; }
        set { _files = value; }
    }

    public void AddTotal(int value)
    {
        Interlocked.Add(ref _total, value);
        OnPropertyChanged("TotalPackets");
    }
}

您不能将 Interlocked.Add(ref _total, value); 添加到 setter 中,因为所需的使用模式仍然是非线程保存:

var total = container.TotalPackets; // #1
total += 10; // #2
container.TotalPackets = total; // #3

#3 中新总值的设置本身是线程安全的,但在#1 和#3 之间,其他线程可能已经更改了总值。如果我们考虑两个线程并且开始总数为 10,则可能会发生以下执行顺序:

  1. 线程 1 - #1 ==> 读取 10
  2. 线程 1 - #2 ==> total 设置为 20
  3. 线程 2 - #1 ==> 读取 10,因为线程 1 尚未 运行 #3
  4. 线程 1 - #3 ==> TotalPackets 设置为 20(初始 10 + 来自 #2/2 的 10。)
  5. 线程 2 - #2 ==> total 在 3 时设置为 20。它仍然是 10
  6. 线程 2 - #3 ==> TotalPackets 再次设置为 20 => boom ;-)