等待似乎悄然返回

问题描述:

我有一个方法调用异步方法的await。等待似乎悄然返回

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()后,我添加了一个循环,不断检查它是否将此文件中的图像添加到字典中。它似乎永远不会被添加,只是挂起。

这种方法在我抽象出来的子类上运行良好。


编辑:

修改有两件事情。一切似乎现在工作,但是当我将结果分配给子类时,我得到一个空的异常错误(即使调试器不指示任何内容为空!)。

我不知道它是否与包裹在任务中的事实有关。

子类:

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 2013-02-28 03:01:12

+0

@pickpg:感谢您对我的思考。如果我在LoadPic上等待,我必须声明方法异步。异步方法必须返回void或,所以没有办法返回我的自定义PixelData类。这在没有等待LoadPic的子类中起作用。 – micahhoover 2013-02-28 03:06:11

你应该避免async void。此外,轮询共享状态以检测异步操作的完成是否定的。这种CPU使用率可能会让您的应用程序被Windows应用商店拒绝。

我建议你更换LoadPic返回Task<PixelData>。然后将ImageDictionaryDictionary<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

啊!异步的学习曲线非常高。异步感染它触及的一切。你必须重新设计一切!我不得不打电话给上面的LoadPic()调用。这至少可以让它编译,但是当我尝试将GrabPixelData(它不为空)的结果赋值给PixelData对象时,出现空异常。 – micahhoover 2013-02-28 03:31:52

+1

为了响应你的编辑,返回'async Task'而不是'async void'和'await'返回的'Task'。关于学习曲线,您可能会发现我的[async/await intro](http://blog.stephencleary.com/2012/02/async-and-await.html)有帮助。 – 2013-02-28 04:24:01

+1

@StephenCleary,你的文章很棒,它终于使我的头吸起了异步的想法并等待着。谢谢! – Snorvarg 2017-06-25 15:06:45