Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# InotifyProperty更改为-c的竞赛条件#_C#_Race Condition_Inotifypropertychanged - Fatal编程技术网

C# InotifyProperty更改为-c的竞赛条件#

C# InotifyProperty更改为-c的竞赛条件#,c#,race-condition,inotifypropertychanged,C#,Race Condition,Inotifypropertychanged,我的场景:有两个组合框带有绑定的SelectedItem属性。 第一个组合框包含成本中心,第二个组合框包含所选成本中心的员工 这意味着如果selectedCostCenter发生更改,INotifyPropertyChanged将激发并搜索CostCenter中的所有员工 视图模型: public abstract class SelectEmployeeViewModel : ViewModelBase { protected readonly Plant plant;

我的场景:有两个组合框带有绑定的
SelectedItem
属性。 第一个组合框包含成本中心,第二个组合框包含所选成本中心的员工

这意味着如果
selectedCostCenter
发生更改,
INotifyPropertyChanged
将激发并搜索CostCenter中的所有员工

视图模型:

  public abstract class SelectEmployeeViewModel : ViewModelBase
{
    protected readonly Plant plant;

    public ObservableCollection<Costcentre> Costcentres { get; protected set; }
    public Costcentre SelectedCostcentre { get; set; }
    public ObservableCollection<Employee> Employees { get; protected set; }
    public Employee SelectedEmployee { get; set; }

    public bool CostcentresEnabled
    {
        get { return Costcentres != null && Costcentres.Any(); }
    }
    public bool EmployeesEnabled
    {
        get { return Employees != null && Employees.Any(); }
    }

    protected SelectEmployeeViewModel(Window window, Page page, Plant plant) : base(window, page)
    {
        this.plant = plant;

        PropertyChanged += SelectEmployeeViewModel_PropertyChanged;
        Costcentres = mainController.CostcentreDao.GetByPlant(plant);
    }

    private void SelectEmployeeViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        switch (e.PropertyName)
        {
            case nameof(SelectedCostcentre):
                SetEmployees();
                break;
        }
    }

    private void SetEmployees()
    {
        if (SelectedCostcentre != null)
            Employees = mainController.EmployeeDao.GetByCostcentre(SelectedCostcentre);
        else
            Employees = new ObservableCollection<Employee>();
    }
}
我如何在没有竞争条件的情况下解决这个问题


谢谢

没有争用条件,因为整个过程都发生在一个线程上

SelectedCostcentre = Costcentres.Single(x => x.Id == employee.Costcentre.Id);

执行
selectedcostcenter
属性的第一个setter,它调用
PropertyChanged
(在您的代码中我没有看到它,但我认为这只是一个输入错误)。这依次调用
SelectEmployeeViewModel\u PropertyChanged
handler和
SetEmployees
。因此,在执行上述行之后-
将为给定的选定
成本中心同步填充员工
,无需任何竞争条件。

哦,很好,谢谢。PropertyChanged在ViewModelBase中,因此您看不到它。是的,但我可以看到
SelectedCostcentre
,它有默认的setter(只是
set
),而我希望它在setter中做些什么来引发属性更改事件。但也许你可以使用像Fody或Postsharp这样的东西来自动为你做这些。我使用的是Fody.PropertyChanged。它确实在构建时创建了setter。如果条件是错误的名称,这是单线程的。您可以使用级联,也可以使用循环事件触发。清楚你所观察到的。
  private void SetEmployee(Employee employee)
    {
        SelectedCostcentre = Costcentres.Single(x => x.Id == employee.Costcentre.Id);
        SelectedEmployee = Employees.Single(x => x.Id == employee.Id);
    }
SelectedCostcentre = Costcentres.Single(x => x.Id == employee.Costcentre.Id);