You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

问题排查与解决方案

  1. 调整同步顺序:先推再拉
    当前代码先执行拉取再推送,但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;
    }
}
  1. 验证Android模拟器网络连接
    确认后端服务在7067端口正常运行,且防火墙未阻止模拟器访问10.0.2.2。可在模拟器浏览器中访问https://10.0.2.2:7067测试连通性。

  2. 简化SQLite连接字符串
    当前用UriBuilder构建的连接字符串可能存在转义问题,改为直接拼接:

var dbPath = Path.Combine(FileSystem.AppDataDirectory, "todoitems.db");
var store = new OfflineSQLiteStore($"file:{dbPath}?mode=rwc");
  1. 添加同步日志排查细节
    在初始化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 12:34:59