【问题标题】:WCF Data Service BeginSaveChanges runs only onceWCF 数据服务 BeginSaveChanges 只运行一次
【发布时间】:2015-05-21 06:20:55
【问题描述】:

我在 Xamarin Forms 应用程序中有以下 WCF 数据服务代码。 它更新表中的一个简单行。

    Static.Dialogs.Alert("Starting");
    DataServiceQuery<SRef.SimpleObject> query = (DataServiceQuery<SRef.SimpleObject>)Entities.SimpleObject.Where(x => x.ID == Guid.Parse("DEF47A0F-AF1E-4043-B8C8-56084841E80B"));
    query.BeginExecute((result) =>
             {
                 try
                 {
                     Static.Dialogs.Alert("Getting the object");
                     var actData = query.EndExecute(result).FirstOrDefault();
                     if (actData != null)
                     {
                         actData.Info = "Info"+randomNumber;
                         Entities.UpdateObject(actData);
                         Entities.ChangeState(actData, EntityStates.Modified);
                         Static.Dialogs.Alert("Before the update");
                         Entities.BeginSaveChanges(SaveChangesOptions.BatchWithIndependentOperations, (result2) =>
                         {
                             try
                             {
                                 Static.Dialogs.Alert("BeginSaveChanges starts");
                                 var r = Entities.EndSaveChanges(result2);
                                 Static.Dialogs.Alert("Update done ");
                             }
                             catch (Exception ex2)
                             {
                                 Static.Dialogs.Alert("Error:" + ex2.Message);
                             }
                         }, null);
                     }
                     else
                         Static.Dialogs.Alert("No object");
                 }
                 catch (Exception ex1)
                 {
                     Static.Dialogs.Alert("Error:" + ex1.Message);
                 }
             }, null);
         }
         catch (Exception ex)
         {
             Static.Dialogs.Alert("Error:" + ex.Message);
         }            
     });

我已经在模拟器和物理设备上测试过了。

有时它完美地工作

有时我只收到以下消息:

  • 开始
  • 获取对象
  • 更新前

有时只有这些:

  • 开始

当我得到一个完美的更新并重试时,它通常会出错。就像它“用完”了唯一的连接,然后它就不起作用了。

在服务器端,我记录了每个错误,但没有捕获任何内容。此外,客户端也不例外。

DataServiceContext MergeOption 设置为 PreserveChanges

什么会影响它?当我发出请求时,我需要等待一段时间吗?我应该以某种方式关闭连接吗?

我认为这是某种缓存问题。

更新

我又试了一次,用更简单的方法(我现在只保存一个新项目):

private DataServiceReference.DataEntities entities;

public DataServiceReference.DataEntities Entities
{
  get
  {
    if (entities == null)
    {
      entities = new DataServiceReference.DataEntities(Static.BaseURI);
      entities.MergeOption = MergeOption.OverwriteChanges;
      entities.SaveChangesDefaultOptions = SaveChangesOptions.ReplaceOnUpdate;
    }
    return entities;
  }
}

var newItem = new DataServiceReference.Info()
{
  Name = "Name " + DateTime.Now.Second,
  ID = Guid.NewGuid(),
  Role = "1"
};
Entities.AddToInfo(newItem);
try
{
  foreach (var item in Entities.Entities)
  {
    System.Diagnostics.Debug.WriteLine(item.Identity + " " + item.State);
  }
  var res = Entities.BeginSaveChanges(SaveChangesOptions.Batch,
      (result) =>
      {
        //var s = 3; //debug point - only hit once
        try
        {
          //back to the UI thread
          Xamarin.Forms.Device.BeginInvokeOnMainThread(() =>
          //(result.AsyncState as DataServiceReference.DataEntities).EndSaveChanges(result));
             Entities.EndSaveChanges(result));
        }
        catch (Exception ex)
        {
          System.Diagnostics.Debug.WriteLine(ex.Message);
          throw;
        }
      }, Entities);
  //res.AsyncWaitHandle.WaitOne(1000); //it only blocks the main thread, no use

  resultList.Add(newItem.Name);
}
catch (Exception ex2)
{
   System.Diagnostics.Debug.WriteLine(ex2.Message);
   throw;
}

我还read(在第一个答案中指出)结果是在不同的线程上提供的,所以我添加了一个调度程序调用来获取结果(注意 UI 线程调用:Xamarin.Forms.Device.BeginInvokeOnMainThread) .

在一个应用程序中,必须在特定的回调上调用 线程,您必须显式编组 End 方法的执行, 它处理对所需线程的响应。例如,在 基于 Windows Presentation Foundation (WPF) 的应用程序和 基于 Silverlight 的应用程序,必须将响应封送回 使用 Dispatcher 上的 BeginInvoke 方法的 UI 线程 对象。

注意End 方法的提及!

我添加了以下调试消息:

foreach (var item in Entities.Entities)
{
  System.Diagnostics.Debug.WriteLine(item.Identity + " " + item.State);
}

结果:

[0:]http://192.168.1.100/InfoDataService/InfoDataService.svc/Info(guid'f1057131-90ee-11d7-9812-0040f6cc1384') Unchanged
[0:]http://192.168.1.100/InfoDataService/InfoDataService.svc/Info(guid'f1057133-90ee-11d7-9812-0040f6cc1384') Unchanged
[0:]http://192.168.1.100/InfoDataService/InfoDataService.svc/Info(guid'f6cfce91-90ef-11d7-9812-0040f6cc1384') Unchanged
[0:]http://192.168.1.100/InfoDataService/InfoDataService.svc/Info(guid'a6c2d822-91a7-11d7-9813-0040f6cc1384') Unchanged
[0:]http://192.168.1.100/InfoDataService/InfoDataService.svc/Info(guid'a6c2d823-91a7-11d7-9813-0040f6cc1384') Unchanged
[0:]http://192.168.1.100/InfoDataService/InfoDataService.svc/Info(guid'a6c2d824-91a7-11d7-9813-0040f6cc1384') Unchanged
[0:]http://192.168.1.100/InfoDataService/InfoDataService.svc/Info(guid'b750e561-91b8-11d7-9813-0040f6cc1384') Unchanged
[0:]http://192.168.1.100/InfoDataService/InfoDataService.svc/Info(guid'b750e562-91b8-11d7-9813-0040f6cc1384') Unchanged
[0:]http://192.168.1.100/InfoDataService/InfoDataService.svc/Info(guid'b750e563-91b8-11d7-9813-0040f6cc1384') Unchanged
[0:]http://192.168.1.100/InfoDataService/InfoDataService.svc/Info(guid'eee2d1f7-17cb-4283-a053-01f6cf7bb2fd') Unchanged
[0:]  Added
[0:]  Added
[0:]  Added

看起来,上下文一直在收集对象,但它只将第一个新对象发送到服务,其他对象不断堆积。

文章强调了End 方法的线程问题,但回调 是这里真正的问题(它没有被触发),所以我们从未接触到End 调用和UI 线程。

这似乎是一个严重的错误,我不知道该怎么办......

【问题讨论】:

    标签: c# wcf-data-services xamarin.forms


    【解决方案1】:

    原因是BeginExecute 将启动另一个线程,即使子线程没有完成,您的主线程也会返回。那么这段代码甚至可能不会执行BeginSaveChanges

    所以要确保所有子线程都完成了。主线程需要等待子线程。

    最简单的方法是System.Threading.Thread.Sleep(5000);或者你可以使用IAsyncResult.AsyncWaitHandle.WaitOne()

    【讨论】:

    • 但是 BeginSaveChanges 函数是 inside 线程并且没有执行 BeginExecute - 所以它必须在线程中运行.我不明白为什么会失败,我一直在检查它。
    猜你喜欢
    • 2022-01-09
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 1970-01-01
    相关资源
    最近更新 更多