首页 > 解决方案 > 如何在循环中使用 PostAsync() 请求?

问题描述

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

这是发送帖子的主要功能

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.netpost

解决方案


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

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

我的建议是,修改您的 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;
        }
    }

推荐阅读