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

C# 如何使用Interlocked.Add更新我的模型计数器值,c#,interlocked,C#,Interlocked,所以我有这个模型: public class Container : INotifyPropertyChanged { private int _total; private static InjectionContainer _mainContainer = new InjectionContainer(); private static InjectionContainer _secondContainer = new InjectionContainer();

所以我有这个模型:

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; }
    }
}
得到了这个错误:

属性或索引器不能作为out或ref参数传递

您应该在容器内创建Add方法:

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

线程1-1==>读取10 线程1-2==>总计设置为20 线程2-1==>读取10,因为线程1还没有运行3 线程1-3==>TotalPackets从2/2开始设置为20初始值10+10。 线程2-2==>total在3时设置为20。当时还是10点 线程2-3=>TotalPackets再次设置为20=>boom-
为什么不让它成为容器的一部分并提供一个Add方法?按ref传递容器的原因是什么?@Matt interlocated.Add的第一个参数必须是refI假设您指的是ref Container.TotalPackets?正如错误所述,您无法传递属性引用,因为与您的情况一样,您传递的不是原语值,而是对setter的引用,而setter实际上是一个可能产生其他副作用的方法。您应该传递对_total字段的引用,但您必须稍微调整代码以将其公开,或者简单地移动联锁的。将调用添加到setter中可以更新代码以保持一致吗?当您的容器没有名为Total的成员时,此时您指的是container.Total。这使得你很难理解你实际上在做什么。我们可以做一些猜测,但这些猜测可能不是您的代码所拥有的。。。此外,您应该澄清错误消息中您不理解的部分。这是一个非常清楚的声明,我个人不确定不理解它的范围是什么…为什么不简单地将调用移动到Interlocated.Add到setter?@haim770,因为这仍然不是线程安全的。如果您读取该值,然后将其递增并设置回原来的值,则该值可能已经更改…另外。。。setter值是一个绝对值,如果您现在使用myContainer.TotalPackages=2表示添加2,则weirdI没有注意到它是AddTotal而不是SetTotal。很明显,他们不是第一个same@ChrFin我可以看到将interlocated.Add放入setter将导致@Jamiec所说的结果,但我不理解interlocated.Addref\u total,setter中的值是线程安全的。编辑:分配部分通过调用Interlocated.Add完成,对吗?
public static void UpdateTotal(Container container, int value)
{
    Interlocked.Add(ref container.Total, value);
}
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");
    }
}
var total = container.TotalPackets; // #1
total += 10; // #2
container.TotalPackets = total; // #3