【发布时间】:2012-10-15 13:17:23
【问题描述】:
下面是我用来访问我正在开发的 Metro 应用程序的资产文件的代码。
async void readFileFromDisk (string fileName, string fileType)
{
string fileContent;
StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(fileName);
using (IRandomAccessStream readStream = await file.OpenAsync(FileAccessMode.Read))
{
using (DataReader dataReader = new DataReader(readStream))
{
UInt32 numBytesLoaded = await dataReader.LoadAsync((UInt32)readStream.Size);
fileContent = dataReader.ReadString(numBytesLoaded);
}
}
此代码在页面的 Loaded 事件处理程序中运行。 我目前收到一个异常,提示“值不在范围内”。错误发生在第一行本身,我尝试从安装文件夹获取 storagefile 句柄。
在调试时,fileName 字符串为 Null。我想,我应该将代码移动到在页面生命周期的后期触发的某个事件,但似乎无法弄清楚最好的地方是什么。建议??
附:我需要在用户进行任何交互之前读取此文件,因为它读取该级别的数据,该用户将与之交互。
编辑:
错过了几件事。 从加载事件的处理程序调用以下函数。
void Game_Loaded(object sender, RoutedEventArgs e)
{
//read all level files to the strings
readFileFromDisk("//Assets/Levels/Start" + selectedLevel + ".txt", "Start");
这个处理程序基本上以类似的方式为不同的文件路径调用上述函数。所选级别的字符串是静态变量,而 fileName 字符串是从中创建的。
编辑 2:
找到了问题,但距离解决方案还很遥远。 readFileFromDist 方法的返回类型引起了麻烦。将其更改为任务,这部分工作正常,但我得到“对象引用未设置为实例”错误。尝试将 Game_Loaded 事件处理程序也转换为异步,以使用 await 运算符,但这给了我“错误返回类型”的编译器错误。
所以,我尝试完全删除异步,但我想我不能这样做。不使用异步功能就无法打开文件。因此,我基本上需要一种方法来调用 readFileFromDisk 函数,使用 await,并在任务完成后继续执行其余代码。类似于函数等待调用的“IsCompleted”事件。
【问题讨论】:
-
您还应该在调用该方法的位置显示代码;你说
fileName是一个静态变量,但它显然是你发布的代码中的一个方法参数。 -
对不起,我的错。我想,如果我犯了这样的愚蠢错误,多任务处理不是我的强项。更新了问题。谢谢。
-
可能不是您的问题的一部分,但在
Game_Loaded中,您正在调用没有await的async方法。一旦您修复了当前的错误,这可能会导致问题!您的async方法也应该有一个返回值 - 有关详细信息,请参阅 this post。 -
其实,async 方法并没有返回任何值。它只是读取文件并将其存储在类变量中。我还需要创建一个 Task
或类似的返回类型并丢弃该值吗?另外,我认为我不能摆脱异步功能并将其转换为正常功能。考虑到要读取的文件只有几 KB 大小,我可以这样做吗?如果允许,我可以在 UI 线程本身中运行文件读取功能。 -
还有一个问题。我需要手动将这些文件复制到 bin 文件夹吗?我刚刚在 Assets 文件夹中添加了引用。