读取文件并同步返回(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;
}
...
}
谢谢斯蒂芬·克利里。我试过你的异步工厂方法,这让我获得了一些成功,但后来我被困在“ReadTextAsync”中。我认为这是一个僵局。我最终删除了所有等待并使用“AsTask()。Result”。 – pakmon
只要你使用['async'],你就不应该有任何死锁问题(http://nitoprograms.blogspot.com/2012/07/dont-block-on-async-code.html) ,正如我在我的博客上解释的那样。 –