【发布时间】: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