当前位置: 首页 > 知识库问答 >
问题:

在foreach中使用HTTPClient实现Async/await

冯通
2023-03-14

我有一个webservice,它加载一些插件并调用它们的过程方法。其中一个插件获取成员列表,并确保它们都包含在MailChimp列表中。

    private async Task AddMCUsers(List<Member> _memberList)
    {
        using (var http = new HttpClient())
        {
            var creds = Convert.ToBase64String(Encoding.ASCII.GetBytes("user:password");
            http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", creds);
            string memberURI = string.Format(@"{0}lists/{1}/members", _baseURI, _memberGroupId);
            var jss = new JavaScriptSerializer();

            foreach (var user in _memberlist)
            {
                var _addStatus = "";

                try
                {
                    var content = jss.Serialize(new MCPost()
                    {
                        email_address = user.Email,
                        status = "subscribed",
                        merge_fields = new MCMergeFields()
                        {
                            FNAME = user.Firstname,
                            LNAME = user.Lastname
                        }
                    });

                    using(var result = await http.PostAsync(memberURI, new StringContent(content,Encoding.UTF8, "application/json")))
                    {
                        var resultText = await result.Content.ReadAsStringAsync();

                        if(result.IsSuccessStatusCode)
                        {
                            _addStatus = "Success";
                            var _returnedUser = jss.Deserialize<MCMember>(resultText);
                            //Store new user's id
                            user.ServiceId = _returnedUser.id;
                        }
                        else
                        {
                            _addStatus = "Fail";
                        }
                    }
                }
                catch {
                    _addStatus = "Error";
                }

                LogEvent("Add User - " + _addStatus, string.Format("Id: {0} - {1} {2} (Account: {3}) : {4}", user.Id, user.Firstname, user.Lastname, user.AccountId, user.Email));

            }
        }
    }

在正常的过程代码中,这不会是一个问题。但是,httpClient上唯一可用的Post方法是PostAsync。对于Async/Await来说,我是相当陌生的,我不确定我的其余代码会有什么影响……特别是因为它涉及到我试图重用httpClient而不是为每个http调用实例化一个新的httpClient。

我不确定当await像我一样被包裹在foreach中时会发生什么。在异步运行时,重用httpClient进行重复调用是否会遇到问题?

我的另一个问题是,实际要返回的是什么。我的理解是等待返回任务。然而,在这里,我正在遍历列表并进行多次调用以等待PostAsync。我的方法返回一个任务。但是哪个任务会被返回呢?如果我的调用方法需要等待完成才能继续,那么它的调用是什么样子的?

private void Process()
{
    //Get List

    var task = AddMCUsers(list);
    task.Wait();

    //Subsequent processing
 }

我读到你应该一直使用异步。这是否意味着我的调用方法应该更像这样?

 public async Task Process()
 {
    //Get list
    ...
    await AddMCUsers(list);

    //Other processing
  }

感谢你在这方面能提供的任何帮助。

共有1个答案

石喜
2023-03-14

在正常的过程代码中,这不会是一个问题。

Async/Await的全部意义在于以一种看起来与“普通”同步代码几乎相同的方式编写异步代码。

对于Async/Await来说,我是相当陌生的,我不确定我的其余代码会有什么影响……特别是因为它涉及到我试图重用httpClient而不是为每个http调用实例化一个新的httpClient。

HttpClient旨在重用;事实上,它可以同时用于任意数量的调用。

我不确定当await像我一样被包裹在foreach中时会发生什么。

一种方法是await“暂停”该方法,直到其操作完成。当操作完成时,方法继续执行。我有一个Async介绍,其中有更详细的内容。

在异步运行时,重用httpClient进行重复调用是否会遇到问题?

不,这很好.

我的理解是等待返回任务。

是的,它应该看起来像您的第二个代码片段:

public async Task ProcessAsync()
{
  //Get list
  ...
  await AddMCUsers(list);

  //Other processing
}

我唯一更改的是Async后缀,这是基于任务的异步模式推荐的。

 类似资料:
  • 问题内容: 在循环中使用/ 是否有任何问题?我试图遍历文件数组和每个文件的内容。 这段代码确实有效,但是这可能会出问题吗?我让某人告诉我,您不应该在这样的高阶函数中使用/ ,所以我只是想问一下这是否有问题。 问题答案: 确保代码确实有效,但是我很确定它不会执行您期望的功能。它只会触发多个异步调用,但此后函数会立即返回。 顺序阅读 如果要顺序读取文件, 则不能使用。只需使用现代循环即可,该循环将按预

  • 我有一个安装了ReactJS的NetCore2应用程序。 null VS代码抛出一个错误,告诉我异步只适用于。ts文件。另外,如果我在任何其他函数中使用await,我将得到一个错误,比如。 据我所知,async/await不仅仅是TS...(或者我错了?)。 谢了!

  • 本文向大家介绍spring boot中使用@Async实现异步调用任务,包括了spring boot中使用@Async实现异步调用任务的使用技巧和注意事项,需要的朋友参考一下 什么是“异步调用”? “异步调用”对应的是“同步调用”,同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行;异步调用指程序在顺序执行时,不等待异步调用的语句返回结果就执行后面的程序。  同

  • 我读到过,在中包含异步是async/await的反模式。下面的代码可以工作,但是我想知道如果没有中的,如何实现相同的结果。 谢了。

  • 问题内容: 我正在尝试为Node v6.9.2配置Babel。我想使用/ 构造。 因为我是Babel和所有Node基础架构的新手,所以我对如何正确配置它感到困惑: 我应该使用什么预设?ES6的大多数功能已经实现了Node。因此,出于性能原因,我不希望Babel移植Node 6.9.x已经支持的功能(箭头功能,新的导入机制等)。 我应该包括哪些插件,以便可以使用异步/等待?我也感到困惑,因为经过一番