2013-09-25 2 views
0

간단한 윈도우 폰에 반환하지 않습니다 여기 내 코드입니다 .HttpClient를 충분히

URL이 정상입니다. 정상적으로로드됩니다.

내 문제는 무엇입니까?

편집 2 : (이제 쓸모 제거)

편집 3 :

나는 당신이 내 데이터의 흐름 무엇을 알려 사용하고 방법을 추가 해요. Page.xaml

<phone:LongListSelector Grid.Row="1" x:Name="UpcomingResultsList" ItemsSource="{Binding UpcomingMovies}" ItemTemplate="{StaticResource MovieListDataTemplate}" Margin="0, 10, 0, 0" /> 

UpcomingMovies

는이 속성

public List<MovieViewModel> UpcomingMovies 
    { 
     get 
     { 
      System.Diagnostics.Debug.WriteLine("UpcomingMovies - Begin");    
      var apiMovies = _serviceRT.FindUpcomingMoviesList().Result; // We get the movies in RT API's format 
      var movies = apiMovies.Select(result => new MovieViewModel(result)).ToList(); 
      System.Diagnostics.Debug.WriteLine("UpcomingMovies - End"); 
      return movies; 
     } 
} 

에 바인딩 된 _serviceRT.FindUpcomingMoviesList() 방법 :

/// <summary> 
/// Gets a list of upcoming movies. 
/// </summary> 
/// <returns>MovieSearchResults</returns> 
public async Task<MovieSearchResults> FindUpcomingMoviesList() 
{ 
    var url = string.Format(LIST_UPCOMING, ApiKey); 
    var jsonResponse = await GetJsonResponse(url); 
    var results = Parser.ParseMovieSearchResults(jsonResponse); 
    return results; 
} 

가 마지막으로 GetJsonResponse() 질문의 시작 부분입니다.

이제 전체 데이터 흐름을 유지하면서이 속성을 바인딩하고 다운로드를 완료 할 수 있습니까?

+0

테스트에서 코드는 완벽하게 작동합니다. 이 문제를 해결하려면 추가 정보가 필요할 수 있습니다. 예를 들어, 수신 한 예외, 다운로드중인 텍스트 컨텐츠의 크기, 에뮬레이터의 인터넷 연결 상태가 실제로 있는지 여부 등을 알 수 있습니다. – lsuarez

답변

1

내가 더 당신의 호출 스택에, 당신은 async 메소드로부터 반환 된 TaskWait 또는 Result를 호출하는 것으로 예측하고있다. This can easily cause deadlock, 내 블로그에서 설명합니다.

await은 기본적으로 async 메서드를 다시 시작하는 데 사용되는 "컨텍스트"를 캡처하기 때문에 발생합니다. 귀하의 예에서는 UI 컨텍스트가 항상 하나의 스레드 (UI 스레드)가 항상있는 UI 컨텍스트 일 ​​가능성이 높습니다. 당신이 Wait 또는 Result를 호출하여 UI 스레드를 차단하면, 다음 async 방법은 실행을 완료하기 위해 UI 컨텍스트를 다시 입력 할 수 없습니다 (당신은 완료 할 수 Task 기다리고 결국).

편집 :

당신이, 내가 (곧 내 AsyncEx 라이브러리의 일부가 될 것입니다)를 NotifyTaskCompletion 유형 here 사용하는 것이 좋습니다 데이터 바인딩하고 이후 :

public MyViewModel() 
{ 
    UpcomingMovies = NotifyTaskCompletion.Create(LoadUpcomingMoviesAsync()); 
} 

public INotifyTaskCompletion<List<MovieViewModel>> UpcomingMovies { get; private set; } 

private async Task<List<MovieViewModel>> LoadUpcomingMoviesAsync() 
{ 
    System.Diagnostics.Debug.WriteLine("UpcomingMovies - Begin");    
    var apiMovies = await _serviceRT.FindUpcomingMoviesList(); 
    var movies = apiMovies.Select(result => new MovieViewModel(result)).ToList(); 
    System.Diagnostics.Debug.WriteLine("UpcomingMovies - End"); 
    return movies; 
} 

그럼 당신은 안전하게에 결합 할 수 있습니다 INotifyTaskCompletion<T>.Result은 다음과 같습니다.

{Binding UpcomingMovies.Result} 

동영상을로드 할 때까지는 결과는 null이되므로보기가 비어 있습니다. 또한 동영상을로드하는 중에 오류가 발생하면보기가 항상 비어있게됩니다. 나는 다른 INotifyTaskCompletion<T> 속성에 데이터 바인딩에 의해 당신이 이러한 상황을 처리하는 것이 예를 들어, 추천 : false을 시작하고 로딩이 완료 될 때 (중 하나를 성공적으로 또는 오류)

  • {Binding UpcomingMovies.IsSuccessfullyCompleted}, true 될 것

    • {Binding UpcomingMovies.IsCompleted}, 어떤 가된다 true 만 로딩이 성공적으로 될
    • {Binding UpcomingMovies.IsFaulted}, 완료 될 때/만약 true 만/경우 로딩 오류
    • 으로 완료 될 때 오류 메시지를 추출하는(오류가없는 경우 null)
  • +0

    요점을 말한 것 같습니다. API를 사용하여 몇 가지 물건을 테스트하기 위해 버튼 클릭 처리기에서 메소드 (directl은 아님)를 호출하고 있습니다. MVVM 패턴을 사용하는'Model'에서 호출을 움직이면 제대로 작동 할 것이라고 생각합니까? 그렇지 않다면 어떻게 해결할 수 있습니까? (이미 블록의 두 번째 솔루션과 같은 것을 사용하고 있습니다. 질문에 전체 코드를 추가하고 있습니다!) – StepTNT

    +0

    문제를 해결하는 가장 좋은 방법은 "async all way"를 사용하는 것입니다. 'Wait' 또는'Result'를'await'으로 바꾸고 거기에서 반복하십시오. 당신의'GetJsonResponse'와'GetJSON'은'async'가되어'async' Loaded 핸들러에서 기다려야합니다 (또는'async' 초기화 패턴을 사용하십시오) (http : //blog.stephencleary .com/2013/01/async-oop-2-constructors.html)을 참조하십시오. –

    +0

    미안하지만 여전히 이해가 안갑니다. 다른 정보를 알려 드리겠습니다. 이 코드는 사용중인 API의 JSON 응답과 일치하는 클래스가 포함 된 UI가없는 라이브러리 (일반 C# 라이브러리)에 있습니다. 이 라이브러리에는 JSON을 가져 와서 다른 프로젝트의'Model' 클래스에서 사용될'Movie' 객체로 파싱하는'GetMovie (int id)'라는 메소드가 있습니다. 이를 위해, 질문에서'GetJsonResponse (string url)'을 호출합니다. 모든 것을 비동기로 만드는 것은'GetMovie '도'Task '과 같은 것을 반환해야한다는 것을 의미합니까? – StepTNT

    0

    HttpClient는 ("큰 창"과 비교하면 Windows Phone의 다른 네트워크 관련 API와 마찬가지로) 호출되는 플랫폼에 따라 제한이 있습니다. 어쩌면, 이것은 어떻게에 도움이됩니다 http://blogs.msdn.com/b/bclteam/archive/2013/02/18/portable-httpclient-for-net-framework-and-windows-phone.aspx

    HttpClientHandler handler = new HttpClientHandler(); 
    httpClient = new HttpClient(handler); 
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, resourceAddress); 
    request.Content = streamContent; 
    if (handler.SupportsTransferEncodingChunked()) 
    { 
        request.Headers.TransferEncodingChunked = true; 
    } 
    HttpResponseMessage response = await httpClient.SendAsync(request);