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

C#中async/await竞态条件问题:如何确保先获取再保存数据

C# async/await 竞态条件解决思路

问题根源

你的代码里竞态条件的核心问题是**async void的滥用**:

  • OnRefresh是async void方法,调用它时无法通过await等待其异步操作完成
  • Dispatcher.InvokeAsync传入的是async void委托,await这个InvokeAsync只能等待委托开始执行,而委托内部的await Task.Delay和OnRefresh会被“火并遗忘”,导致后续的OnSaveTrades提前执行

修复步骤

  1. 将OnRefresh改为返回Task的异步方法
    把async void换成async Task,让调用方可以等待其完成:

    private async Task OnRefreshAsync()
    {
        try
        {
            var trades = await ExchangeServiceInstance.GetTrades("");
            mmTrades = new ObservableCollection<EEtrade>(trades);
            tradeListView.ItemsSource = mmTrades;
        }
        catch { }
    }
    
  2. 修改Dispatcher.InvokeAsync的委托类型
    使用Func<Task>代替Action,并在委托内部await新的OnRefreshAsync,确保所有异步逻辑执行完毕后再继续:

    public async void OnSignalReceived()
    {
        // 现在会等待内部所有异步操作完成后再往下走
        await tradeListView.Dispatcher.InvokeAsync(async () =>
        {
            if (ExchangeServiceInstance.SelectedTabIndex == CURRENT_TAB_INDEX_ITEM)
            {
                await Task.Delay(MMConfig.DELAYMILLISEC);
                await OnRefreshAsync(); // 等待刷新操作完全完成
            }
        });
    
        // 此时mmTrades已经被正确赋值,可安全执行保存
        await OnSaveTrades();
    }
    

关键说明

  • async void仅适合UI事件处理器这类必须无返回值的场景,其他需要等待的异步逻辑必须用async Task/async Task<T>,这样才能通过await构建可靠的异步调用链
  • Dispatcher.InvokeAsync接受Func<Task>时,返回的Task会包含委托内部所有异步操作的完成信号,await它就能确保整个Dispatcher逻辑执行完毕

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:05:21