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

移动端APP同步时触发Logout崩溃的优雅修复方案咨询

移动端APP同步期间触发登出导致崩溃问题

问题背景

  • Sync(同步):同步应用的整体状态与输出信息
  • Logout(登出):执行后会清除所有数据与服务

当同步操作(耗时约2秒)进行时点击Logout,APP会崩溃。原因是线程仍会进入while循环并访问UpdateFrequencyInSeconds字段,此时该字段所属的服务已被登出操作清除,进而引发异常。

原有代码

private async void ThreadSync(CancellationToken token)
{
    while (token.IsCancellationRequested is false)
    {
        await Sync().ConfigureAwait(false);
        await Task.Delay(organizationAppSettingsService.UpdateFrequencyInSeconds * 1000).ConfigureAwait(false);
    }
}

已实现的可行方案(不够简洁优雅)

方案一:

private async void ThreadSync(CancellationToken token)
{
    while (token.IsCancellationRequested is false)
    {
        var updateFrequencyInSeconds = organizationAppSettingsService.UpdateFrequencyInSeconds * 1000;
        await Sync().ConfigureAwait(false);
        await Task.Delay(updateFrequencyInSeconds).ConfigureAwait(false);
    }
}

方案二:

private async void ThreadSync(CancellationToken token)
{
    while (token.IsCancellationRequested is false)
    {
        await Sync().ConfigureAwait(false);
        if (token.IsCancellationRequested is false)
            await Task.Delay(organizationAppSettingsService.UpdateFrequencyInSeconds * 1000).ConfigureAwait(false);
    }
}

无效尝试

曾尝试传入token到Task.Delay:

await Task.Delay(organizationAppSettingsService.UpdateFrequencyInSeconds * 1000, token).ConfigureAwait(false);

但该方式会先获取UpdateFrequencyInSeconds字段值,再检查token状态,无法避免崩溃。

需求

寻求简洁优雅的解决方案,确保在token已取消时不会访问UpdateFrequencyInSeconds字段。

附Sync方法代码

public async Task Sync()
{
    if (networkManager.IsNetworkAvailable is false || IsSyncInProgress ||
        (DateTime.Now - _lastSyncedTime).TotalSeconds < organizationAppSettingsService.UpdateFrequencyInSeconds)
        return;
    IsSyncInProgress = true;
    _logger.LogInformation($"[BackgroundSync] Updating");
    var waiting = Task.Delay(2000);
    ShowSyncProgress?.Invoke();
    try
    {
        UpdateLocation();

        await ordersRepository.UpdateOrders(_courierLocations, _ordersDtos).ConfigureAwait(false);
        var updateServiceInfo = !_lastServiceInfoUpdated.HasValue ||
                                (DateTime.Now - _lastServiceInfoUpdated.Value).TotalSeconds >=
                                IAppSettingsService.DefaultServiceRequestFrequency;
        if (updateServiceInfo)
        {
            await UpdatePaymentTypes().ConfigureAwait(false);
            _lastServiceInfoUpdated = DateTime.Now;
        }

        Synced = true;

        _courierLocations.Clear();
        var orders = Orders?.Where(x => (DateTime.Now - x.DeliveryDate).TotalHours < 24).ToList();
        if (orders is null || orders.Any() is false)
        {
            SyncCompleted?.Invoke();
            return;
        }

        await waiting;
        SyncCompleted?.Invoke();
    }
    catch (SessionExpiredException)
    {
        await RecoverTransportSession().ConfigureAwait(false);
    }
    catch (Exception ex)
    {
        CatchSyncException(ex);
    }
    finally
    {
        _lastSyncedTime = DateTime.Now;

        IsSyncInProgress = false;
        HideSyncProgress?.Invoke();
        _logger.LogInformation("[BackgroundSync] Update completed");
    }
}

内容的提问来源于stack exchange,提问作者rinyasuper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:22:37