2015-07-01 3 views
1

Я застрял в этой проблеме в течение нескольких часов, и я не могу понять это для жизни меня: (Windows.Web.Http.HttpClient.getAsync (uri) подвешивает приложение и не отменяет

Так я использую HttpClient для доступа к XML-файл, размещенный на веб-сайте, который я с использованием в моем приложении.

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

Моя функция заключается в следующем:

public static async Task<string> GetXML() 
{ 
    string xml = string.Empty; 
    Uri url = new Uri("http:/blabla.com/CompanyAppsManifest.xml"); 
    HttpClient hCli = new HttpClient(); 
    CancellationTokenSource cts = new CancellationTokenSource(7000); 
    hCli.DefaultRequestHeaders.TryAppendWithoutValidation("Accept-Encoding", "UTF-8"); 
    hCli.DefaultRequestHeaders.TryAppendWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml, charset=utf-8, text/xml"); 
    try 
    { 
     var response = await hCli.GetAsync(url).AsTask(cts.Token); 
     if (response.IsSuccessStatusCode == true) 
     { 
      xml = response.Content.ToString(); 
      hCli.Dispose(); 
      return xml; 
     } 
     else 
     { 
      hCli.Dispose(); 
      MessageBox.Show("Contact the admin with this info: SC: " + response.StatusCode.ToString() + " Content: " + response.Content.ToString()); 
      if (Debugger.IsAttached) 
      { 
       // An unhandled exception has occurred; break into the debugger 
       Debugger.Break(); 
      } 
      xml = "Operation failed due to: HTTP Failure"; 
      return xml; 
     } 
    } 
    catch (OperationCanceledException) 
    { 
     MessageBox.Show("Operation failed to complete in a timely fashion, please ensure you have WiFi active or a stable data connection"); 
     xml = "Operation failed due to timeout"; 
     return xml; 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("error" + ex.Message + " : " + ex.InnerException.Message); 
     xml = "Operation failed due to exception"; 
     return xml; 
    } 
    finally 
    { 
     cts = null; 
    } 
} 

Он вызывается из метода в открытом классе, который имеет тип возвращаемого значения IEnumerable, однако он не помечен как метод async.

Метод получает строку из моего метода в вопрос, как так

var ss = GetXML().Result; 

Может кто-нибудь сказать мне, почему

1: Маркер отмены не функционирует так, как кажется, во всех примерах я я смотрел. Я не могу понять, где я ошибаюсь.

и 2. Кажется, что это приложение только заморозило приложение при первом запуске, если оно зависает при первом запуске, а затем вы закрываете приложение и перезапускаете его метод getAsync работает нормально, и программа работает как ожидалось.

Любая помощь или совет будет весьма признателен, поскольку я не могу найти ничего, чтобы помочь мне дальше :(

Звуки очень похожи на этот вопрос здесь: How to debug app hanging on Windows Phone 8.1

Я предоставить любую дополнительную информацию требуется только комментарий ниже.

Благодаря

+1

Скорее всего, это тупик, вызванный [блокировкой асинхронного кода] (http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html). – Noseratio

ответ

2

маркер отмены не функционирует так, как кажется, во всех примеры, на которые я смотрел. Я не могу понять, куда я иду .

Это не сработает, потому что ваше приложение блокируется. Я даже не уверен, как он работает во второй раз. Блокировка по асинхронному методу с использованием .Result вызовет тупик. Moreso, вам необходимо использовать перегрузку GetAsync, которая принимает CancellationToken. Обратите внимание, что даже если вы передадите токен, если это взаимоблокировки, это не сработает.

var response = await hCli.GetAsync(url, cts.Token).AsTask(cts.Token); 

кажется, только заморозить приложение при первом запуске, если он замерзает при запуске его в первый раз, а затем закрыть приложение и перезапустить его метод getAsync работает отлично и прогоны программы как ожидается .

Я не уверен, как это возможно. Если вы вызываете это из потока пользовательского интерфейса, он должен запираться каждый раз.

Don't block no async code. Вместо этого пусть он естественным образом перетекает через вашу кодовую базу.Если ваш метод не может использовать async-await и его нужно заблокировать, используйте вместо него синхронный API. Если это не доступно на WP, ну, тогда вам нужно подумать, что вы делаете.