使用BackgroundWorker的ObjectContext.SaveChanges

时间:2012-06-25 11:03:42

标签: wpf entity-framework backgroundworker

我遇到了ObjectContext.SaveChanges方法的问题:

  public void Save(Action<object, object> action)
    {
        EventAggregator.GetEvent<EntityServiceRequestingEvent>().Publish(true);
        var bw = new BackgroundWorker();
        var saved = false;
        bw.DoWork += (o, ee) =>
                         {
                             ProgramStatusService.Status = Resources.DatabaseSavingMessage;


                             if (!CanSave())
                             {
                                 throw new InvalidOperationException(
                                     "You must not call Save when CanSave returns false.");
                             }
                             try
                             {
                                 lock (Context)
                                 {
                                     Context.SaveChanges();
                                     saved = true;    
                                 }
                             }
                             catch (ValidationException e)
                             {
                                 MessageService.ShowError(null, string.Format(CultureInfo.CurrentCulture,
                                                                              Resources.SaveErrorInvalidEntities,
                                                                              e.Message));
                             }
                             catch (UpdateException e)
                             {
                                 var innerException = e.InnerException as SqlException;
                                 if (innerException != null && innerException.Number == 2601)
                                 {
                                     MessageService.ShowError(null, string.Format(CultureInfo.CurrentCulture,
                                                                                  Resources.DublicateKeyUpdateError,
                                                                                  e.InnerException.Message));
                                 }
                                 else
                                 {
                                     MessageService.ShowError(null, string.Format(CultureInfo.CurrentCulture,
                                                                                  Resources.SaveErrorInvalidFields,
                                                                                  e.InnerException.Message));
                                 }
                             }
                             ee.Result = saved;
                         };
        bw.RunWorkerCompleted += (o, e) =>
                                     {
                                         EventAggregator.GetEvent<EntityServiceRequestingEvent>().Publish(false);
                                         ProgramStatusService.Status = Resources.ProgramReadyMessage;
                                         if (e.Result != null) action.Invoke(this, e.Result);
                                     };
        bw.RunWorkerAsync();
    }

保存时我收到错误:调用线程无法访问此对象,因为另一个线程拥有它。在Designer.cs中:

   /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
    [DataMemberAttribute()]
    public Nullable<global::System.DateTime> MDate
    {
        get
        {
            return _MDate;
        }
        set
        {
            OnMDateChanging(value);
            ReportPropertyChanging("MDate");
            _MDate = StructuralObject.SetValidValue(value);
     ReportPropertyChanged("MDate");// **ERROR HERE**

            OnMDateChanged();
        }
    }

如何在BackgroundWorker中正确使用ObjectContext?

1 个答案:

答案 0 :(得分:5)

在后台工作程序中使用上下文的唯一正确方法是在DoWork处理程序中创建它,使用它并在DoWork处理程序结束之前处置它。 ObjectContext不是线程安全的,为SaveChanges锁定它不会改变它。

您收到的异常不是由EF引起的,而是由WPF和UI控件引起的。您无法从非UI线程修改控件。您必须使用Dispatcher来处理控件。