2013-02-28 4 views
0

У меня есть метод, который вызывает ожидание по асинхронному методу.Ожидание, кажется, тихо возвращается

private async void LoadPic(string imageFileName) 
{ 
    StorageFolder sf = Windows.ApplicationModel.Package.Current.InstalledLocation; 
    StorageFolder subFolder = await sf.GetFolderAsync("Assets"); 
    StorageFile sfile = await subFolder.GetFileAsync(imageFileName); 

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

public PixelData GrabPixelData(string imageFileName) 
{ 
    if (!ImageDictionary.ContainsKey(imageFileName)) 
    { 
     // doesn't exist yet, so load it 
     LoadPic(imageFileName); 
    } 

    PixelData pd = new PixelData(); 
    bool found = false; 
    while(found == false) { 
     found = ImageDictionary.TryGetValue(imageFileName, out pd); 
    } 
    return pd; 
    // throw new NullReferenceException(); 
} 

После того как я называю LoadPic() Я добавил цикл, который продолжает проверку, чтобы увидеть, если он добавил изображение в этом файле в словарь. Кажется, он не добавляется и просто зависает.

Этот метод отлично работал на дочернем классе, из которого я его исключил.


Edit:

Модифицированный пару вещей. Кажется, что все работает сейчас, но когда я назначаю результаты дочернему классу, я получаю нулевую ошибку исключения (даже если отладчик не указывает, что что-то пусто!).

Интересно, связано ли это с тем, что оно завернуто в задачу.

класс для детей:

private async void LoadPic() 
{ 
    // I realize the async void is to be avoided, but ... I'm not sure because there isn't anything I want it to return. Should it just return a dummy task? 
    sat1.pixelData = await rootPage.GrabPixelData("sat1.png"); 

LoadPic:

 private async Task<PixelData> LoadPic(string imageFileName) 
     { 
      StorageFolder sf = Windows.ApplicationModel.Package.Current.InstalledLocation; 
      StorageFolder subFolder = await sf.GetFolderAsync("Assets"); 
      StorageFile sfile = await subFolder.GetFileAsync(imageFileName); 
... 
      return pd; 

GrabPixelData:

public async Task<PixelData> GrabPixelData(string imageFileName) 
{ 
    if (!ImageDictionary.ContainsKey(imageFileName)) 
    { 
     // doesn't exist yet, so load it 
     PixelData pd = await LoadPic(imageFileName); 
     ImageDictionary.Add(imageFileName, pd); 
    } 

    var test = ImageDictionary[imageFileName]; 

    return ImageDictionary[imageFileName]; 
} 
+0

Как вы никогда не '' await' на LoadPic', он будет возвращаться туда и продолжить выполнение в предположении, что вам не нужно ждать его (поэтому используется в качестве асинхронный, пожарный и забытый метод). Я бы ожидал, что он в конце концов ударит по вашей точке останова, когда те вернутся, но я на самом деле не использовал C# недавно для проверки. – pickypg

+0

@pickpg: Спасибо, что подумал об этом со мной. Если я жду на LoadPic, я должен объявить метод async. Асинхронные методы должны возвращать void или , и поэтому нет способа вернуть мой собственный класс PixelData. Это работало в дочернем классе без ожидания на LoadPic. – micahhoover

ответ

4

Вы должны избегать async void. Кроме того, опрос общего состояния для обнаружения завершения асинхронной операции - нет-нет. Такое использование ЦП может отменить ваше приложение из хранилища Windows.

Я рекомендую вам изменить LoadPic, чтобы вернуть Task<PixelData>. Затем измените свой ImageDictionary с Dictionary<string, PixelData> на Dictionary<string, Task<PixelData>>. Ваш метод GrabPixelData может выглядеть следующим образом:

public Task<PixelData> GrabPixelData(string imageFileName) 
{ 
    if (!ImageDictionary.ContainsKey(imageFileName)) 
    { 
    // doesn't exist yet, so load it 
    ImageDictionary.Add(imageFileName, LoadPic(imageFileName)); 
    } 

    return ImageDictionary[imageFileName]; 
} 
+0

Ах! Кривая обучения в async настолько высока. Async заражает все, что касается. Вы должны все перестраивать! Я должен был позвонить в ожидании вызова LoadPic() выше. Это, по крайней мере, требует компиляции, но почему-то возникает исключительное исключение, когда я пытаюсь назначить результаты GrabPixelData (который не является нулевым) объекту PixelData. – micahhoover

+1

Чтобы ответить на ваши изменения, верните 'async Task' вместо' async void' и 'await' возвращенную' Task'. Что касается кривой обучения, вы можете найти мое [async/wait intro] (http://blog.stephencleary.com/2012/02/async-and-await.html) полезным. –

+1

@ StephenCleary, ваша статья замечательная, она, наконец, заставила мою голову сосать идею асинхронного движения и ждать. Спасибо! – Snorvarg

Смежные вопросы