2012-09-02 1 views
4

내 Windows 8 응용 프로그램에 일부 데이터가 있으며이 정적 데이터는 일부 정적 데이터입니다. 사실 : 이것은 deserialize되어야하는 간단한 xml 파일입니다.WinRT : GetFileFromApplicationUriAsync()를 사용하여 정적 데이터로드

데이터는 Assets \ data.xml에 저장됩니다 (자산은 빈 응용 프로그램 템플릿의 기본 폴더 임).

나는 그것을 액세스하기 위해이 코드 조각을 사용하고 있습니다 :

private static async Task<MyObject> Load() 
{ 
    if (Windows.ApplicationModel.DesignMode.DesignModeEnabled) 
    { 
     return new SampleData(); 
    } 

    var uri = new Uri("ms-appx:///Assets/data.xml"); 
    Debug.WriteLine("Getting file from Application"); 
    var file = await StorageFile.GetFileFromApplicationUriAsync(uri); 
    Debug.WriteLine("Opening file for reading async"); 
    var stream = await file.OpenStreamForReadAsync(); 

    var serializer = new XmlSerializer(typeof(MyObject)); 

    Debug.WriteLine("Begin deserialization"); 
    var result = (MyObject)serializer.Deserialize(stream.AsInputStream().AsStreamForRead()); 

    return result; 
} 

호출 방법 :

public static MyObject GetMyObject() 
{ 
    if (_myObject == null) 
    { 
     _myObject = Load().Result; 
    } 

    return _myObject; 
} 

그에 대한 "재미"부분은 다음과 같습니다

내가 설정 한 경우 breakpoint가 var uri = new Uri(...);이고 F11을 사용하여 코드를 단계별 실행하면 모든 것이 예상대로 작동합니다. 나는 모든 디버그 라인을 얻었고 나의 애플리케이션은 원하는대로 정적 데이터를 보여준다.

중단 점을 설정하지 않고 코드 조각을 단계적으로 수행하지 않으면 디버그 출력이 Getting a file from Application이고 그 이상은 발생하지 않습니다. GetFileFromApplicationUriAsync()가 결코 돌아 오지 않는 것 같습니다. 나는 5 분 이상 기다렸지 만 여전히 아무 일도 일어나지 않았습니다.

아무도 모르게됩니다.

+0

몇 가지 소스 코드를 게시 할 수 있습니까? 특히 위의 코드와 그 메소드를 호출하는 방법의 예제에서 전체 메소드를 게시하십시오. – Alexander

+0

@Alexander 코드 –

답변

11

코드를 게시 해 주셔서 감사합니다. 다음과 같은 Load 귀하의 방법을 변경하여보십시오 :

//your code 
var file = await StorageFile.GetFileFromApplicationUriAsync(uri).AsTask().ConfigureAwait(false); 
//your code 
var stream = await file.OpenStreamForReadAsync().ConfigureAwait(false); 
//your code 

여기에 가장 큰 차이점은 AsTask()이다 (false)를 ConfigureAwait을 편집

:.이 좋은

들을 수 있다는 일. 설명은 매우 간단합니다 : GUI 슬롯에 또는 task.Wait()을 사용하면 await 키워드와 함께 교착 상태가 발생합니다. 이는 awaiting 코드가 호출 된 동일한 컨텍스트 (예 : GUI 스레드)에서 다시 실행되기 때문에 발생합니다. 그리고 현재 작업 완료를 기다리는 GUI 스레드 (Result 또는 Wait()) 때문에 교착 상태가 발생하고 await 키워드 이후의 코드는 호출되지 않습니다. ConfigureAwait(false)은 현재 컨텍스트를 무시할 수 있도록 지정하므로 코드를 성공적으로 완료 할 수 있습니다. 이에 대한 자세한 내용은 여기를 참조하십시오. http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

+0

을 추가했습니다. 정말 멋지게 보입니다! 답변을 향상시키고 이것이 정확히 무엇을하고 있는지 설명하기 위해 친절하십니까? 그리고 두 번째 변경 라인에서는'AsTask()'를 제거해야합니다. 당신은'await file.OpenStreamForReadAsync(). ConfigureAwait (false);'를 사용할 수있다. –