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

Blazor Server异步任务调用引发父任务重复执行问题求助

Blazor Server中LoadDataForScheduler因Graph API异步调用重复执行的解决方案

可能的原因

Blazor Server的组件渲染依赖状态变更触发重渲染,异步操作完成后会自动调用StateHasChanged。如果LoadDataForScheduler的触发逻辑(比如绑定到生命周期方法、UI回调)与状态变更形成循环,就会导致重复执行。此外,Graph API调用过程中若意外修改了组件绑定的参数(如用户邮箱),也会触发组件重渲染并再次调用该方法。

解决方案

1. 添加防重复执行标记

在组件中维护一个加载状态标记,执行LoadDataForScheduler前检查是否正在加载,避免重复触发:

private bool _isLoading = false;

public async Task LoadDataForScheduler(SchedulerArgs args)
{
    if (_isLoading) return;
    try
    {
        _isLoading = true;
        // 调用Graph API获取数据
        List<Appointment> outlookAppointments = await _graphController.GetAllEventsForUser(userEmail, args.Start, args.End);
        // 更新调度器数据逻辑
    }
    finally
    {
        _isLoading = false;
    }
}

2. 排查触发时机与生命周期绑定

  • 确认LoadDataForScheduler是否绑定在OnParametersSetAsync这类生命周期方法中,若用户选择变更导致参数重复更新,会反复触发该方法。可通过对比参数变更前后的值,仅在实际变化时执行加载:
    private string _previousUserEmail;
    
    protected override async Task OnParametersSetAsync()
    {
        if (_previousUserEmail != userEmail)
        {
            _previousUserEmail = userEmail;
            await LoadDataForScheduler(currentSchedulerArgs);
        }
    }
    
  • 检查调度器组件的事件绑定(如DataBinding)是否被重复注册,导致回调多次触发。

3. 使用CancellationToken取消重复请求

维护一个CancellationTokenSource,每次触发加载时取消之前未完成的请求,避免重复执行:

private CancellationTokenSource _loadCts;

public async Task LoadDataForScheduler(SchedulerArgs args)
{
    // 取消之前的请求
    _loadCts?.Cancel();
    _loadCts?.Dispose();
    _loadCts = new CancellationTokenSource();

    try
    {
        // 将令牌传入Graph API调用
        List<Appointment> outlookAppointments = await _graphController.GetAllEventsForUser(userEmail, args.Start, args.End, _loadCts.Token);
        // 更新调度器数据
    }
    catch (OperationCanceledException)
    {
        // 忽略已取消的请求
    }
    finally
    {
        _loadCts.Dispose();
        _loadCts = null;
    }
}

同时修改GetAllEventsForUser方法,传入取消令牌:

public async Task<List<Appointment>> GetAllEventsForUser(string email, DateTime start, DateTime end, CancellationToken cancellationToken = default)
{
    var response = await _graphServiceClient.Users[email].Events.GetAsync((requestConfiguration) =>
    {
        requestConfiguration.QueryParameters.Expand = new string[] { "singleValueExtendedProperties($filter=id eq 'String {00020329-0000-0000-C000-000000000046} Name proplanid')" };
        requestConfiguration.QueryParameters.Filter = $"start/dateTime ge '{start:o}' and end/dateTime le '{end:o}'";
        requestConfiguration.QueryParameters.Top = 99;
        requestConfiguration.Options.WithAppOnly();
        requestConfiguration.Options.ToDynamicList();
    }, cancellationToken);

    // 转换为Appointment列表并返回
}

4. 检查状态变更源

排查GetAllEventsForUser方法或Graph API响应处理逻辑中,是否意外修改了组件绑定的参数(如userEmail)或其他触发重渲染的状态,导致组件反复刷新并调用加载方法。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 05:28:14