我在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);
}
});
我已在模拟器和物理设备上测试过它。
有时它完全 。
有时我只收到这些消息:
有时只有这些:
当我得到一个完美的更新并且我再试一次时,它大多会出错。就像它已经用完了#39;唯一的联系,之后它不起作用。
在服务器端,我记录每个错误,没有任何东西被捕获。此外,客户端也不例外。
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线程调用:{{ 1}})。
在必须针对特定内容调用回调的应用程序中 线程,你必须显式编组End方法的执行, 它处理响应,到所需的线程。例如,在 基于Windows Presentation Foundation(WPF)的应用程序和 基于Silverlight的应用程序,响应必须被整理回来 在Dispatcher上使用BeginInvoke方法的UI线程 对象
请注意提及Xamarin.Forms.Device.BeginInvokeOnMainThread
方法!
我添加了以下调试消息:
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
方法的线程问题,但回调是真正的问题(它没有被触发),所以我们永远不会到{{1}调用和UI线程。
这似乎是一个严重的错误,我不知道该怎么做......
答案 0 :(得分:0)
原因是BeginExecute
将启动另一个线程,即使子线程未完成,您的主线程也会返回。那么这段代码甚至可能不会执行BeginSaveChanges
。
所以要确保所有子线程完成。主线程需要等待子线程。
最简单的方法是System.Threading.Thread.Sleep(5000)
;或者您可以使用IAsyncResult.AsyncWaitHandle.WaitOne()