MAUI离线同步报错:todo表推送后仍存在未完成操作
MAUI离线数据同步Android模拟器报错:同步推送后仍有未处理操作
我正在开发一款支持离线数据同步的MAUI应用,在Android模拟器中调用Sync方法时出现以下错误:
Microsoft.Datasync.Client.DatasyncInvalidOperationException: 'There are still pending operations for table 'todo' after a push'
但Windows应用调试时同步功能运行正常。
SyncAsync方法代码
public async Task SyncAsync() { if (!_initialized) return; ReadOnlyCollection<TableOperationError> syncErrors = null; try { //foreach (var offlineTable in offlineTables.Values) //{ var pullOptions = new PullOptions { PushOtherTables = true, WriteDeltaTokenInterval = 25 }; await table.PullItemsAsync(pullOptions); //Error here... await table.PushItemsAsync(); //} } catch (PushFailedException exc) { if (exc.PushResult != null) { syncErrors = (ReadOnlyCollection<TableOperationError>)exc.PushResult.Errors; } } }
离线初始化代码
private async void Init() { if (_initialized) return; //Create offline definition var dbPath = Path.Combine(FileSystem.AppDataDirectory, "todoitems.db"); //var store = new OfflineSQLiteStore($"file:/{dbPath}?mode=rwc"); var connectionString = new UriBuilder { Scheme = "file", Path = dbPath, Query = "?mode=rwc" }.Uri.ToString(); var store = new OfflineSQLiteStore(connectionString); store.DefineTable<ToDo>(); var options = new DatasyncClientOptions { OfflineStore = store, //IdGenerator = (table) => Guid.NewGuid().ToString("N"), InstallationId = null, //ParallelOperations = 1, SerializerSettings = null, //TableEndpointResolver = (table) => $"/tables/{tableName.ToLowerInvariant()}", UserAgent = $"Datasync/5.0 (/* Device information */)" }; //Create the data sync client string baseAddress = DeviceInfo.Platform == DevicePlatform.Android ? "https://10.0.2.2:7067" : "https://localhost:7067"; client = new DatasyncClient(baseAddress, options); //Initialize database await client.InitializeOfflineStoreAsync(); //Get reference to the offline table table = client.GetOfflineTable<ToDo>(); // Set _initialized to true to prevent duplication of locking. _initialized = true; }
问题排查与解决方案
- 调整同步顺序:先推再拉
当前代码先执行拉取再推送,但PullOptions中PushOtherTables = true仅会推送其他表的待处理操作,当前表的操作未被处理,导致拉取时检测到未完成的推送操作。正确流程应先推送当前表操作,再拉取数据:
try { // 先推送当前表的待处理操作 await table.PushItemsAsync(); // 拉取数据时自动推送其他表操作 var pullOptions = new PullOptions { PushOtherTables = true, WriteDeltaTokenInterval = 25 }; await table.PullItemsAsync(pullOptions); } catch (PushFailedException exc) { if (exc.PushResult != null) { syncErrors = (ReadOnlyCollection<TableOperationError>)exc.PushResult.Errors; } }
验证Android模拟器网络连接
确认后端服务在7067端口正常运行,且防火墙未阻止模拟器访问10.0.2.2。可在模拟器浏览器中访问https://10.0.2.2:7067测试连通性。简化SQLite连接字符串
当前用UriBuilder构建的连接字符串可能存在转义问题,改为直接拼接:
var dbPath = Path.Combine(FileSystem.AppDataDirectory, "todoitems.db"); var store = new OfflineSQLiteStore($"file:{dbPath}?mode=rwc");
- 添加同步日志排查细节
在初始化DatasyncClient时添加日志,查看同步过程的详细状态:
options.HttpPipeline.AddPolicy(new HttpMessageHandlerPolicy((request, next) => { System.Diagnostics.Debug.WriteLine($"Request: {request.Method} {request.RequestUri}"); return next.SendAsync(request, CancellationToken.None); }));
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

