首页 > 解决方案 > 如何优化此代码并每 40ms 调用一次 Api

问题描述

我想询问一个返回 JSON Rest Api 响应的传感器。我每 40 毫秒调用一次 Api,但它给了我这个错误:

在 System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) 在 System.Threading.Tasks.Task1.get_Result()

我有计时器 where interval= 40。这是我如何调用 tha Api 的代码:

 private void Timer(object sender, EventArgs e)
        {
            tmrPollingSick.Stop();

            string strJson = "";
           
            HttpClient client = new HttpClient();
            string baseUrl = "http://9999.99999.99999.8";
            client.BaseAddress = new Uri(baseUrl);
            var contentType = new MediaTypeWithQualityHeaderValue("application/json");
            client.DefaultRequestHeaders.Accept.Add(contentType);
            string strAltezza = string.Empty;
            try
            {
                strJson = "Here I set HEADERS... DATA ect " + Convert.ToChar(34) +
                        "header" + Convert.ToChar(34) + ": {............" 

                var contentData = new StringContent(strJson, System.Text.Encoding.UTF8, "application/json");
                using (var responseMessage = client.PostAsync("/bla/bla/bla", contentData).Result)
                {
                    if (responseMessage.IsSuccessStatusCode)
                    {
                        string strContext = responseMessage.Content.ReadAsStringAsync().Result;

                        Object dec = JsonConvert.DeserializeObject(strContext);     // deserializing Json string (it will deserialize Json string)

                        JObject obj = JObject.Parse(strContext);
                        //Process Data In
                        JObject obj1 = JObject.Parse(obj["bla"].ToString());
                        JObject obj2 = JObject.Parse(obj1["processDataIn"].ToString());
                        strAltezza = obj2["1"].ToString();
                        textBox1.Text = strAltezza;

                    }
                }
            }

        catch(WebException ex1)
        {
            MessageBox.Show("web: "+ex1.StackTrace.ToString() + " - " + ex1.Message);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.StackTrace.ToString() + " - " + ex.Message);
        }
        tmrPollingSick.Start();
    }

一切正常,但过了一段时间它给了我这个错误。我已经读过这个(如何为网页实现实时数据这个),但我还没有尝试过。任何建议如何解决这个问题?有没有另一种方法可以在不崩溃的情况下实时获得结果?

标签: c#apirest

解决方案


当您在 40 毫秒内调用此方法时,您将用完发送套接字,因为您每次都会创建一个新的HttpClient. 即使将其放入using语句(导致HttpClientimplements IDisposable)也无法解决此问题,因为底层套接字将被操作系统阻塞 3 分钟(请查看此答案以获得进一步的解释)。

您应该将这些内容拆分为一些初始化阶段,在其中设置客户端,尽可能构建请求,并在此计时器方法中调用该PostAsync()方法并检查响应。


推荐阅读