我已经根据 Microsoft 提供的文档/示例实现了 Azure - 离线同步Sample https://github.com/Azure/azure-mobile-apps-quickstarts/blob/master/client/xamarin.forms/ZUMOAPPNAME/TodoItemManager.cs在我的 Xamarin Forms 应用程序中。
在提供的示例/文档中,他们使用默认的服务处理程序。
// 简单的错误/冲突处理。真实的应用程序将通过 IMobileServiceSyncHandler 处理各种错误,例如网络状况、服务器冲突等。
因为我需要实施一个重试逻辑3次 if the 拉/推失败。根据文档,我创建了一个自定义服务处理程序(IMobileServiceSyncHandler).
请在这里找到我的代码逻辑。
public class CustomSyncHandler : IMobileServiceSyncHandler
{
public async Task<JObject> ExecuteTableOperationAsync(IMobileServiceTableOperation operation)
{
MobileServiceInvalidOperationException error = null;
Func<Task<JObject>> tryExecuteAsync = operation.ExecuteAsync;
int retryCount = 3;
for (int i = 0; i < retryCount; i++)
{
try
{
error = null;
var result = await tryExecuteAsync();
return result;
}
catch (MobileServiceConflictException e)
{
error = e;
}
catch (MobileServicePreconditionFailedException e)
{
error = e;
}
catch (MobileServiceInvalidOperationException e)
{
error = e;
}
catch (Exception e)
{
throw e;
}
if (error != null)
{
if(retryCount <=3) continue;
else
{
//Need to implement
//Update failed, reverting to server's copy.
}
}
}
return null;
}
public Task OnPushCompleteAsync(MobileServicePushCompletionResult result)
{
return Task.FromResult(0);
}
}
但我不知道如何处理/恢复服务器副本,以防 3 次重试全部失败。
在 TODO 示例中,他们在哪里恢复它基于移动服务推送失败异常。但是当我们实施时这是可用的IMobileServiceSyncHandler。
更重要的是,如果我们包含自定义 IMobileServiceSyncHandler 它不会执行之后的代码推异步/拉异步。如果出现任何异常,即使 try catch 也不会触发。
try
{
await this.client.SyncContext.PushAsync();
await this.todoTable.PullAsync(
//The first parameter is a query name that is used internally by the client SDK to implement incremental sync.
//Use a different query name for each unique query in your program
"allTodoItems",
this.todoTable.CreateQuery());
}
catch (MobileServicePushFailedException exc)
{
if (exc.PushResult != null)
{
syncErrors = exc.PushResult.Errors;
}
}
// Simple error/conflict handling. A real application would handle the various errors like network conditions,
// server conflicts and others via the IMobileServiceSyncHandler.
if (syncErrors != null)
{
foreach (var error in syncErrors)
{
if (error.OperationKind == MobileServiceTableOperationKind.Update && error.Result != null)
{
//Update failed, reverting to server's copy.
await error.CancelAndUpdateItemAsync(error.Result);
}
else
{
// Discard local change.
await error.CancelAndDiscardItemAsync();
}
Debug.WriteLine(@"Error executing sync operation. Item: {0} ({1}). Operation discarded.", error.TableName, error.Item["id"]);
}
}
}
Note
在我的应用程序中,我只想在出现任何服务器错误时重试 3 次。我并不是要寻求解决冲突。这就是我没有添加相同代码的原因。
如果有人遇到类似问题并解决了,请帮忙。
Stez.