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

.NET MAUI中Activity Indicator显示时机异常问题求助

解决ActivityIndicator延迟显示的问题

你的问题根源在于同步网络请求阻塞了UI线程。当你在按钮点击事件里执行WebClient.DownloadString这类同步方法时,整个UI线程会被卡住,无法立即更新ActivityIndicator的显示状态——直到所有同步操作(地图设置、网络请求、数据解析、TreeView绑定)全部完成,UI才会刷新,这就导致Indicator看起来是在数据加载完成后才出现。

改用异步操作释放UI线程,让UI能及时响应Indicator的显示指令,具体修改步骤如下:

1. 修改按钮点击事件为异步方法

在方法签名前添加async关键字,同时加入异常处理和按钮状态控制,避免重复点击:

async void btIndicatorOn_Clicked(System.Object sender, System.EventArgs e)
{
    // 立即显示Indicator
    acIndicator.IsVisible = true;
    acIndicator.IsRunning = true;
    // 禁用按钮防止重复触发
    btIndicatorOn.IsEnabled = false;

    try
    {
        // 执行地图相关UI操作
        mapa.IsVisible = true;
        mapa.MoveToRegion(MapSpan.FromCenterAndRadius(new Location(41.21301, 1.73250), Distance.FromMiles(0.5)));
        string cadenaSituacion = " 41.21º  N  1.73º  E";
        var pin = new Pin
        {
            Label = cadenaSituacion,
            Address = cadenaSituacion,
            Type = PinType.Place,
            Location = new Location(41.21301, 1.73250)
        };
        mapa.Pins.Add(pin);

        // 异步调用数据加载方法
        await ObtenerPrevisionAsync();
    }
    catch (Exception ex)
    {
        // 这里可以添加异常处理逻辑,比如提示用户网络错误
        // 例如:await DisplayAlert("错误", "加载数据失败:" + ex.Message, "确定");
    }
    finally
    {
        // 无论成功失败,都隐藏Indicator并恢复按钮状态
        acIndicator.IsVisible = false;
        acIndicator.IsRunning = false;
        btIndicatorOn.IsEnabled = true;
    }
}

2. 将数据加载方法改为异步

替换过时的WebClient为更推荐的HttpClient,并将方法改为异步模式:

// 全局复用HttpClient实例,避免频繁创建导致Socket资源浪费
private readonly HttpClient _httpClient = new HttpClient();

public async Task ObtenerPrevisionAsync()
{
    string url = string.Format("http://api.openweathermap.org/data/2.5/forecast?units=metric&lat={0}&lon={1}&lang=es&APPID={2}", 
                              viewModel.LatitudMapa, viewModel.LongitudMapa, OpenWeatherKey);

    // 异步获取JSON数据,不阻塞UI线程
    var json = await _httpClient.GetStringAsync(url);
    var forecast = JsonConvert.DeserializeObject<weatherForecast>(json);

    // 清空旧数据,避免重复累积
    DatosPrevision.Clear();
    foreach (var item in forecast.list)
    {
        DatosPrevision.Add(new TreeViewNode(item.dt_txt)
        {
            Children =
            {
                new TreeViewNode(item.weather[0].description),
                new TreeViewNode($"Temperatura {String.Format("{0:N1}", item.main.temp)} ºC"),
                new TreeViewNode($"Dirección Viento {String.Format("{0:N1}", item.wind.deg)} º"),
                new TreeViewNode($"Velocidad Viento {String.Format("{0:N1}", ((item.wind.speed * 3600) / 1852))} Nudos"),
                new TreeViewNode($"Presión atmosférica sobre el suelo {item.main.grnd_level} hPa"),
                new TreeViewNode($"Presión atmosférica sobre el mar {item.main.sea_level} hPa"),
                new TreeViewNode($"Humedad {item.main.humidity}%"),
            }
        });
    }
    // 更新TreeView数据源,await后默认回到主线程,无需额外切换
    tvPrevision.ItemsSource = DatosPrevision;
}

额外优化建议

  • 全局复用HttpClient:不要每次请求都创建新实例,避免Socket资源耗尽。
  • 数据清空逻辑:每次加载新数据前清空DatosPrevision,避免数据重复显示。
  • 异常提示:在catch块中添加用户友好的错误提示,提升体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:42:42