【问题标题】:How to use PostAsync() Request in a Loop?如何在循环中使用 PostAsync() 请求?
【发布时间】:2021-03-30 17:21:28
【问题描述】:

我需要为List<> 上的每个对象发送一个POST

这是发送帖子的主要功能

public async Task<string> Set(int pessoaId)
{
    try
    {
        Pessoas pessoa = new PessoasBLL().SelectBy("PessoaID", pessoaId);
        List<Endereco> lstEndereco = new EnderecoBLL().SelectByEntidade(pessoaId);
        Person person = new Person();

        person = SerializePerson(person, pessoa, lstEndereco);


        string token = new IntegracaoBLL().Select().ToUpper();
        // Put the following code where you want to initialize the class
        // It can be the static constructor or a one-time initializer
        if (client.BaseAddress == null)
        {
            client.BaseAddress = new Uri(baseURL);
        }
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic", token);

        var data = JsonConvert.SerializeObject(person);

        var request = new StringContent(JsonConvert.SerializeObject(person), Encoding.UTF8, "application/json");

        var postResponse = await client.PostAsync("person", request);

        if (postResponse.StatusCode == HttpStatusCode.Created || postResponse.StatusCode == HttpStatusCode.NotAcceptable)
        {
            new PessoasBLL().SetImportacao(pessoaId, true);
        }

        return null;
    }
    catch (Exception ex)
    {
        return null;
    }
}

该函数在不在循环中时也可以正常工作,例如:

private void btnTeste_Click(object sender, EventArgs e)
{
    new IntegrationWebApi().Set(8).ConfigureAwait(true);             
}

但我无法让这个“代码”循环工作,例如这样

private void btnTeste_Click(object sender, EventArgs e)
{
    try
    {
        List<Pessoas> pessoas = new PessoasBLL().SelectAllIntegracao();
        foreach (Pessoas p in pessoas)
        {
            new IntegrationWebApi().Set(p.ID).ConfigureAwait(true);
        }
    }
    catch (Exception ex)
    {
        XtraMessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
        new Logger().LogEntry(ex);
    }
}

【问题讨论】:

    标签: c# json .net post


    【解决方案1】:

    这是在黑暗中的一个镜头,但我猜你认为它不起作用,因为你的程序在完成工作之前没有响应,这是一个巨大的请求循环。但实际上它是有效的,只是效率不高。

    首先,在 UI 线程的 for 循环中创建 POST 请求听起来并不那么高效。如果 pessoas 列表有很多成员,您的循环将等待 POST 请求完成以继续进行下一次迭代。并且由于这个 foreach 循环在 UI 事件 (btnTeste_Click) 内,所以在所有 POST 请求完成之前,您的 UI 不会响应(基本上冻结)。

    我建议修改您的 Set() 函数以接受 List 作为参数而不是整数,因此 foreach 循环将在异步服务而不是 UI 线程内工作,这将减轻 UI 线程上的负载。

    所以您的新函数将如下所示: (请注意,我并没有费心重命名所有的东西。仔细阅读并在粘贴和执行之前重构它以满足您的需要。由于您使用本地语言定义了变量,我无法胜任完全了解后果,所以这种方法可能不适合你。)

    private void btnTeste_Click(object sender, EventArgs e)
        {
            try
            {
                List<Pessoas> pessoas = new PessoasBLL().SelectAllIntegracao();
                new IntegrationWebApi().Set(pessoas).ConfigureAwait(true);
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
                new Logger().LogEntry(ex);
            }
    

    你的功能会是这样的;

        public async Task<string> Set(List<Pessoa> pessoas)
        {
            try
            {
                foreach(var pessoa in pessoas)
            {
                Pessoas newPessoa = new PessoasBLL().SelectBy("PessoaID", pessoaId);
                List<Endereco> lstEndereco = new 
                EnderecoBLL().SelectByEntidade(pessoaId);
                Person person = new Person();
    
                person = SerializePerson(person, newPessoa, lstEndereco);
    
    
                string token = new IntegracaoBLL().Select().ToUpper();
                // Put the following code where you want to initialize the class
                // It can be the static constructor or a one-time initializer
                if (client.BaseAddress == null)
                {
                    client.BaseAddress = new Uri(baseURL);
                }
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue("application/json"));
                client.DefaultRequestHeaders.Authorization =
                    new AuthenticationHeaderValue("Basic", token);
    
                var data = JsonConvert.SerializeObject(person);
    
                var request = new StringContent(JsonConvert.SerializeObject(person), Encoding.UTF8, "application/json");
    
                var postResponse = await client.PostAsync("person", request);
    
                if (postResponse.StatusCode == HttpStatusCode.Created || 
        postResponse.StatusCode == HttpStatusCode.NotAcceptable)
                {
                    new PessoasBLL().SetImportacao(pessoaId, true);
                }
    }
    
                return null;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    

    【讨论】:

    • 非常感谢,这正是我需要做的,而不是调用多个不对称任务,我的项目只调用一个效率更高。
    猜你喜欢
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 2020-06-07
    • 2020-12-20
    • 1970-01-01
    • 2023-03-16
    相关资源
    最近更新 更多