首页 > 解决方案 > 来自 Blazor 中组件的异步 Http 请求

问题描述

我在 Blazor 中创建了一个组件列表,这些组件中的每一个都需要从网页请求一些数据。该列表在 .razor 页面上按如下方式创建:

@foreach(stringcomp in Complist){
   <myComponent />
}

创建了大约 100 个组件。在所有这些组件上,都会执行以下 URL 请求(使用此代码):

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                await GetUrl("some url here");
            }
        }


        public async Task<string> GetUrl(string url)
        {
            HttpClient client = new HttpClient();
            var request = new HttpRequestMessage(HttpMethod.Get, url);
            request.Headers.Add("User-Agent", "get data service");
            var response = await client.SendAsync(request).ConfigureAwait(false);
            string res = null;
            if (response.IsSuccessStatusCode)
            {
                using var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
                var streamReader = new StreamReader(responseStream);
                res = await streamReader.ReadToEndAsync().ConfigureAwait(false);
            }
            return res;
        }

这样做我遇到了一些问题,我对SendAsync的大多数调用都不会返回值。我已经明白这是因为锁定状态,但我一生都无法弄清楚如何解决它。最相似的答案建议设置.ConfigureAwait (false)但这并没有在我的情况下产生不同的结果。

所以我的问题是:我可以在不同的组件中同时请求网页,并确保它们不会挂起/查找。由于有许多请求有时需要很长时间(5-10 秒)才能完成,因此同步执行它们并不是一种替代方法。

值得一提的是,我的代码和页面是分开的,每个 .razor 页面都使用 @inherits 来获取其功能/逻辑

标签: async-awaitblazordotnet-httpclientblazor-server-side

解决方案


尝试按如下方式使用 IHttpClientFactory:

[Inject] public IHttpClientFactory clientFactory { get; set;}
using System.IO;

您的 GetUrl 方法:

 public async Task<string> GetUrl(string url)
{
    var request = new HttpRequestMessage(HttpMethod.Get, url);
    request.Headers.Add("Accept", "application/json");
    request.Headers.Add("User-Agent", "get data service");


    var client = clientFactory.CreateClient();

    var response = await client.SendAsync(request);

    string res = null;

    if (response.IsSuccessStatusCode)
    {
        using var responseStream = await response.Content.ReadAsStreamAsync();
        var streamReader = new StreamReader(responseStream);
        res = await streamReader.ReadToEndAsync().ConfigureAwait(false);
    }

    return res;
}

启动.cs

 public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpClient();

    // More code here...
 }

希望这有效...


推荐阅读