HttpClient.GetByteArrayAsync(…) “взаимоблокировка” при отсутствии подключения к Интернету в стандартной библиотеке .NET, вызываемой из UWP

#c# #uwp #dotnet-httpclient #.net-standard

#c# #uwp #dotnet-httpclient #.net-стандартный

Вопрос:

Я разрабатываю приложение UWP для системы управления документами. Я пытаюсь открыть документы из своего приложения. Когда я нажимаю на открытый документ, он загружает документ, а затем открывается в приложении по умолчанию. Но проблема в том, что документ не загружается, если Интернет отключается в середине процесса. Это означает, что httpClinet уже вызван. Мой код выглядит следующим образом

    public async Task<DownloadFileDetail> DownloadFileAsync(int dmsFileId)
    {
        if (dmsFileId <= 0)
        {
            throw new ArgumentException("Invalid DMS File Id");
        }
        try
        {
            return await Task.Run(async () =>
              {
                  DownloadFileDetail fileDetail = new DownloadFileDetail()
                  {
                      DocId = dmsFileId
                  };
                  string apiUrl = $"files/download/latest/{dmsFileId}";
                  HttpClient httpClient = new HttpClient();
                  httpClient.BaseAddress = new Uri(BaseApiUrl);
                  httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {SessionStore.Instance.AuthToken}");
                  var response = await httpClient.GetByteArrayAsync(apiUrl); --> gone deadlock
                  fileDetail.Content = response;
                  return fileDetail;
              });
        }
        catch (Exception ex)
        {

        }
        return new DownloadFileDetail()
        {
            DocId = dmsFileId
        };
    }
 

Процесс загрузки вызывается как UWP-> Стандартная библиотека .NET (содержит приведенный выше код). Будет здорово, если кто-нибудь поможет мне решить проблему.

Спасибо ss

Обновление: приведенный выше код работает на моем ноутбуке и не работает ни на одном другом ноутбуке в среде разработки

Комментарии:

1. Почему вы используете Task.Run API для выполнения загрузки в фоновом потоке? Также обратите внимание, что существует свойство Timeout .

2. Я попробовал тайм-аут, это также не решило проблему

3. Не могли бы вы попробовать добавить .ConfigureAwait(false); в конец обоих операторов await? Ожидание может блокировать ваш поток пользовательского интерфейса, что приводит к взаимоблокировке.

4. Я попробую выше

5. что заставляет вас думать, что это именно взаимоблокировка? что-то не завершенное — это не то же самое, что взаимоблокировка

Ответ №1:

при отсутствии подключения к Интернету в стандартной библиотеке .NET, вызываемой из UWP

Если взаимоблокировка возникает только в среде без подключения к Интернету, вы можете проверить, доступен ли Интернет перед отправкой http-запроса. Пожалуйста, проверьте это NetworkHelper .

 if (NetworkHelper.Instance.ConnectionInformation.IsInternetAvailable)
{
// sending the request.
}
 

Комментарии:

1. взаимоблокировка начинается, когда Интернет отключается в середине httpclient делает запрос. Imeans ожидает HttpClient. GetByteArrayAsync(apiUrl) уже запущен.

2. приведенный выше код работает на моем одном ноутбуке, но не на другом ноутбуке, я протестировал его на 3 других ноутбуках, но не на всех.

3. Он содержит NetworkChanged , вы можете отменить запрос вручную, когда сеть недоступна.

4. Рабочая машина выдает исключение из HRESULT: сообщение 0x80072EFE при отключении сети

5. какая строка выдает это исключение

Ответ №2:

Сначала удалите Task.Run(async () => ...) вызов:

 try
{
  DownloadFileDetail fileDetail = new DownloadFileDetail()
  {
      DocId = dmsFileId
  };
  string apiUrl = $"files/download/latest/{dmsFileId}";
  HttpClient httpClient = new HttpClient();
  httpClient.BaseAddress = new Uri(BaseApiUrl);
  httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {SessionStore.Instance.AuthToken}");
  var response = await httpClient.GetByteArrayAsync(apiUrl); --> gone deadlock
  fileDetail.Content = response;
  
  return fileDetail;
}
 

Комментарии:

1. теперь, когда это сделано, пожалуйста, добавьте, как вы вызываете этот метод

2. Я звоню из браузера с пользовательским протоколом, который открывает наше приложение UWP, а затем UWP начинает загрузку файла

3. сделайте эту точку входа для этого метода uwp асинхронной и ожидайте вызова DownloadFileAsync. Если вы не предоставите больше информации об окружающем коде, мы не сможем вам помочь.

4. Он работает с любыми изменениями на моем ноутбуке, но не работает ни на одном другом ноутбуке.