【问题标题】:HttpClient long polling interrupted by seperate threadHttpClient长轮询被单独的线程中断
【发布时间】:2019-10-03 22:35:16
【问题描述】:

我正在运行一个消息服务机器人,它使用长轮询工具来发送用户消息。这一切都很好,直到我添加了一个新组件,它每 30 秒向心跳监控服务发送一个简单的 http get 请求。实现此组件后,每当心跳组件发送其请求时,我的机器人代码都会向消息传递服务发送一个额外的轮询请求。

我假设心跳组件发送的请求正在中断长轮询,或者类似的东西?如果我注释掉心跳请求,一切正常。

我尝试过使用共享的 HttpClient,并在使用后单独处置 HttpClient。

心跳监测代码:

                using (var client = new HttpClient())
                {
                    var response = await client.GetAsync(_heartbeatUrl);

                    var responseString = await response.Content.ReadAsStringAsync();

                    if (!response.IsSuccessStatusCode)
                    {
                        Log.LogMessage(response.ReasonPhrase, LogType.Error);
                        Log.LogMessage(responseString, LogType.Error);
                    }
                    Log.LogMessage(responseString, LogType.Verbose);
                }

消息机器人投票代码:

                using (var client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
                    var jsonData = JsonConvert.SerializeObject(data);

                    var content = new StringContent(jsonData, Encoding.UTF8, "application/json");

                    var fullString = _url + "/" + methodName;

                    Log.LogMessage("Querying: " + fullString, LogType.Verbose);
                    Log.LogMessage("With Data: " + jsonData, LogType.Verbose);

                    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, fullString)
                    {
                        Content = content,
                    };
                    request.Headers.Authorization = new AuthenticationHeaderValue("mybot", _botToken);

                    var response = await client.SendAsync(request);

                    var responseString = await response.Content.ReadAsStringAsync();
                    returnedObject = JsonConvert.DeserializeObject<T>(responseString);

                    if (!response.IsSuccessStatusCode)
                    {
                        Log.LogMessage(response.ReasonPhrase, LogType.Error);
                        Log.LogMessage(responseString, LogType.Error);
                    }

                    Log.LogMessage(responseString, LogType.Verbose);
                }

这两个都是在简单的 while(true) 循环中调用的,即

                Thread th = new Thread(async a =>
                {
                    while (true)
                    {
                        await SendHeartbeat();
                        Thread.Sleep(30000);
                    }
                });

            new Thread(async () =>
            {
                while (true)
                {
                    try
                    {
                        var results = await Methods.getUpdates(_service, update_id);

                    } catch (Exception e) { Log.LogMessage("Error with HTML query: " + e.Message, LogType.Error, e.StackTrace); }
                }
            }).Start();

我有点不知道是什么原因造成的。任何建议都非常感谢!

【问题讨论】:

    标签: c# dotnet-httpclient


    【解决方案1】:

    最后想通了。我对静态 Log 类的调用锁定了文件写入方法。我相信当心跳运行并记录它的结果时,轮询代码会在尝试记录内容时被阻止,从而导致线程被异步等待释放。一个新线程将在前一个线程完成执行之前开始轮询。

    【讨论】:

      猜你喜欢
      • 2012-10-01
      • 2017-05-15
      • 2014-03-29
      • 2023-01-10
      • 1970-01-01
      • 1970-01-01
      • 2020-06-14
      • 2013-08-08
      • 1970-01-01
      相关资源
      最近更新 更多