读取文件并同步返回(Metro应用程序)

问题描述:

我正在写一个Metro应用程序。 我想读取一个文件并从数据中返回一个float []。但不管我做什么,函数似乎都返回null。我已经尝试过类似问题的解决方案,但没有运气。读取文件并同步返回(Metro应用程序)

例如,如果我使用:
浮子[] floatArray =新ModelReader( “FILENAME.TXT”)ReadModel()
其结果将是一个空数组。

但是,如果我使用:
新ModelReader(“FILENAME.TXT”)
正确的阵列将被打印到控制台,因为“测试”也返回之前打印阵列。这对我来说似乎很奇怪。

请给我一些指导,我不知道什么是错的。

public class ModelReader 
{ 
    float[] array; 

    public ModelReader(String name) 
    { 
     ReadModelAsync(name); 
    } 

    public float[] ReadModel() 
    { 
     return array; 
    } 

    private async Task ReadModelAsync(String name) 
    { 
     await readFile(name); 
    } 

    async Task readFile(String name) 
    { 
     // settings 
     var path = @"Assets\models\" + name; 
     var folder = Windows.ApplicationModel.Package.Current.InstalledLocation; 

     // acquire file 
     var file = await folder.GetFileAsync(path); 

     // read content 
     var read = await Windows.Storage.FileIO.ReadTextAsync(file); 
     using (StringReader sr = new StringReader(read)) 
     { 
      Test test = new Test(getFloatArray(sr)); 
      this.array = test.printArray(); 
     } 
    } 

    private float[] getFloatArray(StringReader sr) { ... } 


public class Test 
{ 
    public float[] floatArray; 

    public Test(float[] floatArray) 
    { 
     this.floatArray = floatArray; 
    } 


    public float[] printArray() 
    { 
     for (int i = 0; i < floatArray.Length; i++) 
     { 
      Debug.WriteLine(floatArray[i]); 
     } 

     return floatArray; 
    } 

} 

您试图在完成之前获取异步操作的结果。我建议你阅读我的intro to async/await并跟进async/await FAQ

特别是你的构造:

public ModelReader(String name) 
{ 
    ReadModelAsync(name); 
} 

ReadModelAsync返回之前完成。由于构造函数不能是异步的,我建议您使用异步工厂或asynchronous lazy initialization,如我的博客中所述(也可在我的AsyncEx library中找到)。

下面是使用异步工厂方法一个简单的例子:

public class ModelReader 
{ 
    float[] array; 

    private ModelReader() 
    { 
    } 

    public static async Task<ModelReader> Create(string name) 
    { 
    var ret = new ModelReader(); 
    await ret.ReadModelAsync(name); 
    return ret; 
    } 

    ... 
} 
+0

谢谢斯蒂芬·克利里。我试过你的异步工厂方法,这让我获得了一些成功,但后来我被困在“ReadTextAsync”中。我认为这是一个僵局。我最终删除了所有等待并使用“AsTask()。Result”。 – pakmon

+0

只要你使用['async'],你就不应该有任何死锁问题(http://nitoprograms.blogspot.com/2012/07/dont-block-on-async-code.html) ,正如我在我的博客上解释的那样。 –