【问题标题】:Async and Await didn't work on web apiAsync 和 Await 在 web api 上不起作用
【发布时间】:2015-09-28 17:13:23
【问题描述】:

我正在尝试在我的异步方法上使用 await,但它不起作用。我在调用post方法时输入了2个参数数组,只插入了最后一个 到数据库(我使用 Elasticsearch 作为数据库,所以当 _id 相同时,文档将被新文档替换)。我发现当插入尚未完成时,程序已经运行以查询数据库,结果为 0,所以它再次插入而不是更新。 我已经在我的程序中添加了等待,但没有成功。谁能帮我解决这个问题?谢谢

这是我的代码

 // POST api/values
    [HttpPost]
    public async Task<AvatarModel.AvatarResponse> Post(MultiLanguageTemp[] LangTemp)
    {

        //process param to multilanguage model
        AvatarModel.AvatarResponse Resp = new AvatarModel.AvatarResponse();
        try
        {
            for (int i = 0; i < LangTemp.Length; i++)
            {
                string Type = LangTemp[i].Type;
                if ("ErrorCode".Equals(Type))
                {


                }
                else
                {
                    string GetLabelId = LangTemp[i].LabelId;
                    string GetTranslation = LangTemp[i].Translation;

                    MultiLanguage Lang = new MultiLanguage();
                    Lang.Type = LangTemp[i].Type;
                    Lang.Site = LangTemp[i].Site;
                    Lang.Language = LangTemp[i].LangId;
                    Lang.Source = LangTemp[i].Source;
                    Lang.TranslationList = new Dictionary<string, string>();
                    Lang.TranslationList.Clear();
                    Lang.TranslationList.Add(GetLabelId, GetTranslation);



                    //search elasticsearch first using id TYPE+SITE+LANG_ID+SOURCE

                    string ESResponse = await GetMultiLangAsync(Lang);
                    JObject GetResp = JObject.Parse(ESResponse);


                    //get elasticsearch Hits count
                    JToken GetHitsTotal = GetResp.SelectToken("hits.total");
                    int Hits = int.Parse(GetHitsTotal.ToString());

                    // if id exist then do update else do insert
                    if (Hits > 0)
                    {
                         string ResponseUpdate = await UpdateMultiLangAsync(GetLabelId, GetTranslation,Lang);

                      if (!ResponseUpdate.ToString().ToUpper().Contains("ERROR"))
                        {
                            Resp.Result = "0000000";
                            Resp.Message = "Update MultiLanguage Info is Success";
                        }
                        else
                        {
                            Resp.Result = "9000003";
                            Resp.Message = "Update MultiLanguage Info into ES failed";
                        }
                    }
                    else
                    {
                        //tasks.Add(InsertMultiLangAsync(Lang));

                        //insert new document into elasticsearch
                        string InsertESResponse = await InsertMultiLangAsync(Lang);
                        if (!InsertESResponse.ToUpper().Contains("ERROR"))
                        {
                            Resp.Result = "0000000";
                            Resp.Message = "Insert MultiLanguage Info is Success";
                        }
                        else
                        {
                            Resp.Result = "9000003";
                            Resp.Message = "Insert MultiLanguage Info into ES failed";
                        }
                    }
                }

            }

        }
        catch (Exception E)
        {
            Resp.Result = "9000005";
            Resp.Message = E.Message.ToString();
        }
        return Resp;
    }

    public async Task<string> GetMultiLangAsync(MultiLanguage Lang)
    {
        var Client = new HttpClient();
        Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/MultiLangInfo/");
        Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        var Query = "{\"query\": {\"match\": {\"_id\":\"" + Lang.Type + Lang.Site + Lang.Language + Lang.Source + "\"}}}";
        var StringContent = new StringContent(Query, Encoding.UTF8, "application/json");
        var Response =  Client.PostAsync("_search", StringContent).Result.Content.ReadAsStringAsync();

        //JObject GetResp = JObject.Parse(Response.Result);
        return await Response;
    }

    public async Task<string> InsertMultiLangAsync(MultiLanguage Lang)
    {
        var Client = new HttpClient();
        Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/");
        Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        var JsonTextMultiLang = JsonConvert.SerializeObject(Lang, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
        var StringContent = new StringContent(JsonTextMultiLang, Encoding.UTF8, "application/json");
        var ResponseInsert = Client.PostAsync("MultiLangInfo/" + Lang.Type + Lang.Site + Lang.Language + Lang.Source, StringContent).Result.Content.ReadAsStringAsync();

        return await ResponseInsert;
    }

    public async Task<string> UpdateMultiLangAsync(string GetLabelId,string GetTranslation, MultiLanguage Lang)
    {
        var UpdateES = "{\"doc\":{\"TranslationList\":{\"" + GetLabelId + "\":\"" + GetTranslation + "\"}},\"detect_noop\":true}";

        var Client = new HttpClient();
        Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/MultiLangInfo/" + Lang.Type + Lang.Site + Lang.Language + Lang.Source + "/");
        Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        var StringContent = new StringContent(UpdateES, Encoding.UTF8, "application/json");
        var ResponseUpdate = Client.PostAsync("_update", StringContent).Result.Content.ReadAsStringAsync();
        return await ResponseUpdate;
    }

【问题讨论】:

  • 我不太明白。所以你说你有两个请求,第一个是发出的,在它完成之前,第二个调用会导致重复?所以你试图通过等待第一个电话完成来避免这种情况?
  • 是的,我想等待第一个完成,然后继续程序。首先我需要检查数据库中是否存在参数,如果不存在,我将插入数据库并更新。我使用 for 循环来做到这一点。这是我的参数看起来像 [{"Type":"ErrorCode", "Site":"Default","LangId":"en","Source":"error","LabelId":"0000001","Translation ":"AVATAR 系统用户不存在"},"Type":"ErrorCode","Site":"Default","LangId":"en","Source":"error","LabelId":"0000002 ","Translation":"域 ID 或密码不正确。" }] 。谢谢
  • 请发布一个最小的、可重现的示例。

标签: asp.net-web-api elasticsearch async-await


【解决方案1】:

这是我的见解。

根据您提供的详细信息,您有一个长期运行的任务,最终会在您的数据库中创建/更新一条记录。现在,您遇到的问题是您发送的第二个 http 请求并没有等待第一个请求完成,即使您使用的是 async/await 模式。好吧,这不是它的工作原理。无论您做什么,无论您是否阻塞线程,都会存在线程池,并且不同的 http 调用将拥有自己的线程。所以使用 async/await 根本不会影响它。在大多数情况下,您正确地使用了 async/await。但是,您要实现的目标不是由 async/await 完成的。您可能想尝试使用消息传递系统对所有请求进行排队。在这种情况下,你不能让客户端暂停,你会生成一个请求 id 并立即将其发送给他们,并及时异步处理请求。

【讨论】:

  • 谢谢。我会试试的。
猜你喜欢
  • 2021-11-18
  • 1970-01-01
  • 2020-12-07
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-24
  • 2018-06-09
相关资源
最近更新 更多