Бросив исключение через некоторое время - PullRequest
0 голосов
/ 11 апреля 2019

Я подключаюсь к устройству, используя команду пут над URL.Однако для установки требуется, чтобы асинхронная команда находилась внутри таймера.Некоторое время он работает нормально, затем mscorlib.dll начинает выдавать исключения, и команды перестают отправляться.

Я попытался добавить асинхронный вызов в обработчик событий таймера и дождаться функции, которая вызывает команду, но это все равно происходит,Не уверен на 100%, как это должно быть, потому что таймер не может ждать, и это происходит очень быстро.

button click {
_updateTimer = new Timer(_updateInterval);
_updateTimer.Tick += new EventHandler(TimerUpdate_Tick);
Start
}

private async void TimerUpdate_Tick(object sender, System.EventArgs e)
{
   //do other very important stuff that has to be in timer update event
   await myfunction();
}

public static async Task myfunction()
{
    HttpClientHandler handler = new HttpClientHandler();

    using (var httpClient = new HttpClient(handler))
    {
       using (var request = new HttpRequestMessage(new HttpMethod("PUT"), address))
       {
           request.Content = new StringContent("hello");
           var response = await httpClient.SendAsync(request);
           //after some time, it gives an exception on this SendAsync saying connection closed. I did try reconnecting but still gives it again.
        }
    }            
}

Я хочу очистить некоторый буфер, если это проблема, и сохранить соединение живым и запросы отправляются.как они делают в течение первых 15 секунд.Я не уверен, что асинхронность, ожидания и задачи используются правильно.

Спасибо

1 Ответ

2 голосов
/ 11 апреля 2019

Если вы можете некоторое время выполнить запросы , а затем они не выполняются, возможно, вы исчерпали количество доступных сокетов.Это может произойти, когда мы неоднократно создаем и располагаем HttpClient для каждого запроса.

Вместо этого мы должны создать HttpClient и использовать его как можно дольше.Технически мы должны избавиться от него, когда мы закончим с ним, потому что он реализует IDisposable, но мы не будем делать это до тех пор, пока мы продолжаем его использовать.Таким образом, правильный способ использовать и утилизировать его не на 100% ясен.

Документация гласит:

HttpClient предназначен для однократного создания и повторного использования в течение всего жизненного цикла приложения.Создание класса HttpClient для каждого запроса приведет к исчерпанию количества сокетов, доступных при больших нагрузках.Это приведет к ошибкам SocketException.Ниже приведен пример правильного использования HttpClient.

... и следующий за ним пример:

public class GoodController : ApiController
{
    // OK
    private static readonly HttpClient HttpClient;

    static GoodController()
    {
        HttpClient = new HttpClient();
    }
}

Другая альтернатива - использовать что-то отличное от HttpClient. RestSharp не только очень прост в использовании, но и не использует HttpClient, поэтому вам не нужно беспокоиться об утилизации.Он обрабатывает множество подобных вещей изнутри.

Кроме того, вот забавная статья , которая привлекла мое внимание.

...