Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.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# 工作MvvM和并发性_C#_Wpf_Mvvm_Concurrency - Fatal编程技术网

C# 工作MvvM和并发性

C# 工作MvvM和并发性,c#,wpf,mvvm,concurrency,C#,Wpf,Mvvm,Concurrency,我正在使用WPF和MvvM开发一个用C#编写的应用程序。我仍然是MvvM和实体框架的一些概念的初学者。除了并发性问题,我的一切似乎都在运行。我经历了这一切,但这对我来说不起作用。因此,与MvvM结构一样,我有一个名为BackflowManagementEntities的模型和实体文件。然后,我有一个存储库来处理测试人员的更新。我在这里试着接球,但是运气不好 private BackflowManagementEntities dbContext; internal void SaveChange

我正在使用WPF和MvvM开发一个用C#编写的应用程序。我仍然是MvvM和实体框架的一些概念的初学者。除了并发性问题,我的一切似乎都在运行。我经历了这一切,但这对我来说不起作用。因此,与MvvM结构一样,我有一个名为BackflowManagementEntities的模型和实体文件。然后,我有一个存储库来处理测试人员的更新。我在这里试着接球,但是运气不好

private BackflowManagementEntities dbContext;
internal void SaveChanges()
{
      try
      {
           dbContext.SaveChanges(); 
      }
      catch (DBConcurrencyException ex)
      {
           Console.WriteLine("Concurrency Exception : " + ex.Message);
      }
}
所以我有一个三部分的问题:

  • 这是我能想到的唯一应该实现并发检查的地方。如果我错了,请告诉我
  • 这是检查并发错误的正确异常/方法吗?我知道如何处理并发错误,只是不知道如何捕捉它
  • 你有没有什么可以推荐我阅读的关于处理和捕获并发异常的资料
  • 查看MSDN文章

    默认情况下,实体框架 实现乐观并发 模型这意味着锁不可用 保留在数据源中的数据上 在查询数据时与 数据已更新。实体 框架将对象更改保存到 数据库,不检查 并发性。对于可能 经验丰富 并发性,我们建议 实体在中定义属性 属性为的概念层 ConcurrencyMode=“fixed”,如中所示 下面是一个例子:

    任何冲突的更改都将导致

    有关详细信息,请参阅


    简言之,将
    ConcurrencyMode
    更改为Fixed并捕获
    OptimisticConcurrencyException
    异常…

    我知道我已经很晚了,但这是许多开发人员在使用实体框架和wpf开发多线程应用程序时面临的问题。 现在有几件事你必须注意

  • )无法从后台线程访问ui线程
  • )Dbcontext不是线程安全的,因此在多线程环境中使用它 如果不小心,环境可能会导致问题
  • 下面是我解决这个问题的方法。我的解决方案遵循抽象存储库模式。 参与课程和接口包括:

  • 数据存储库和IDataRepository

     public interface IDataRepository 
            {
                void AddAsync<T>(T entity, Action<T>callBack,Action<Exception>exceptionCallback=null) where T : EntityBase;
                void DeleteAsync<T>(int[] ids, Action callBack, Action<Exception> exceptionCallback = null) where T : EntityBase;
                void UpdateAsync<T>(T entity, Action<T> callBack, Action<Exception> exceptionCallback = null) where T : EntityBase;
                void FindAsync<T>(int id, Action<T> callBack, Action<Exception> exceptionCallback = null) where T : EntityBase;
               void FindAsync<T>(Action<List<T>> callBack,Expression<Func<T, bool>> predicate=null, int? pageIndex=0, int? pageSize=20, params Expression<Func<T, object>>[] includes) where T : EntityBase;
            }
    
  • 学生和学生

  • 学生视图模型

  • 实体库

  • 这是我的地址

     public interface IDataRepository 
            {
                void AddAsync<T>(T entity, Action<T>callBack,Action<Exception>exceptionCallback=null) where T : EntityBase;
                void DeleteAsync<T>(int[] ids, Action callBack, Action<Exception> exceptionCallback = null) where T : EntityBase;
                void UpdateAsync<T>(T entity, Action<T> callBack, Action<Exception> exceptionCallback = null) where T : EntityBase;
                void FindAsync<T>(int id, Action<T> callBack, Action<Exception> exceptionCallback = null) where T : EntityBase;
               void FindAsync<T>(Action<List<T>> callBack,Expression<Func<T, bool>> predicate=null, int? pageIndex=0, int? pageSize=20, params Expression<Func<T, object>>[] includes) where T : EntityBase;
            }
    

    这正是我想要的。非常感谢您的快速响应。请注意,在生产过程中,我使用mef作为DI来导入存储库。事实上,我使用了一种称为RepositoryFactory Patrn的好模式来实现这一点。有关完整的源代码,您可以通过suulisindiyaka@stoicteam.com
      public interface IStudentRepository:IDataRepository
        {
             void AddGuardian(Gurdian gurdian, int studentId,Action<Student> callBack);
             void SaveStudent(Student student, Gurdian gurdian,Action<Student>callBack);         
             void GetPrimaryGurdian(int studentId,Action<Gurdian> callBack );
            
        }
    
    
    
    
    [Export(typeof(IStudentRepository))]
        [PartCreationPolicy(CreationPolicy.NonShared)]
        public class StudentRepository : Repository<StudentContext>, IStudentRepository
        {
            public void AddGuardian(Gurdian gurdian, int studentId, Action<Student> callBack)
            {
               FindAsync<Student>(studentId, (student) =>
               {
                   student.Gurdians.Add(gurdian);
                   UpdateAsync(student, callBack);
               });
            }
    
            public void SaveStudent(Student student, Gurdian gurdian, Action<Student> callBack)
            {
              student.Gurdians.Add(gurdian);
                AddAsync(student, callBack);
            }
    
            public void GetPrimaryGurdian(int studentId, Action<Gurdian> callBack)
            {
               FindAsync<Student>(studentId,(student)=> { callBack(student.PrimaryGurdian); });
            }
        }
    
    [Export]
        [PartCreationPolicy(CreationPolicy.Shared)]
        public class StudentViewModel : ViewModelBase
        {        
           
            private readonly IStudentRepository _repository;
    
            [ImportingConstructor]
            public StudentViewModel()
            {
                          
                _repository =new StudentRepository();
    
                Student = new Student();         
                SaveStudentCommand = new RelayCommand(OnStudentSaveExcute, CanSaveStudent);
               
            }
    
           
    
            #region Properties
            private Student _student;
    
            public Student Student
            {
                get { return _student; }
                set { _student = value; OnPropertyChanged(() => Student); }
            }
    
          
            private ObservableCollection<Student> _students = new ObservableCollection<Student>();
    
            public ObservableCollection<Student> Students
            {
                get { return _students; }
                set { _students = value; }
            }
    
           
    
            #endregion
    
            #region Commands
            public ICommand SaveStudentCommand { get; set; }
    
    
            private void OnStudentSaveExcute()
            {
              
                
                _repository.SaveStudent(Student,Gurdian, (student) =>
                {
                    _students.Add(student);
                });
    
            }
           
            #endregion
           
    
            private  void LoadStudents()
            {
                
                _repository.FindAsync<Student>((students) =>
                {
                    foreach(var student in students)
                    _students.Add(student);
                });
            }
         
        }
    
    public class EntityBase{
    public int get{get;set;}
    }