Windows store apps Windows运行时GetFileFromPathAsync未返回
我希望有人能对我遇到的问题有所了解。我正在编写一个Windows应用商店应用程序,启动时需要将“种子”数据库从应用程序安装文件夹Windows store apps Windows运行时GetFileFromPathAsync未返回,windows-store-apps,Windows Store Apps,我希望有人能对我遇到的问题有所了解。我正在编写一个Windows应用商店应用程序,启动时需要将“种子”数据库从应用程序安装文件夹Windows.ApplicationModel.Package.Current.InstalledLocation.Path复制到本地数据文件夹Windows.Storage.ApplicationData.Current.LocalFolder。为此,我在Main()中使用了从我的OnNavigatedTo方法调用的以下命令 受保护的覆盖无效OnNavigatedT
Windows.ApplicationModel.Package.Current.InstalledLocation.Path
复制到本地数据文件夹Windows.Storage.ApplicationData.Current.LocalFolder
。为此,我在Main()
中使用了从我的OnNavigatedTo
方法调用的以下命令
受保护的覆盖无效OnNavigatedTo(NavigationEventArgs e)
{
//调用Dal类中的方法,以确保数据库位于正确的位置,如果不在,则复制它
Dal.LoadData();
RefreshScenarioList();
ScenarioList.SelectedIndex=0;//这是默认项
}
公共静态异步void LoadData()
{
等待CopyIfNotExists(dbName);
}
私有静态异步任务CopyIfNotExists(字符串dbName)
{
if(wait GetIfFileExistsAsync(dbName)==null)
{
StorageFile seedFile=等待StorageFile.GetFileFromPathAsync(
Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path,
数据库名);
等待seedFile.copyanc(Windows.Storage.ApplicationData.Current.LocalFolder);
}
}
私有静态异步任务GetIffileExistsAsSync(字符串键)
{
尝试
{
返回wait-wait-ApplicationData.Current.LocalFolder.GetFileAsync(键);
}
catch(FileNotFoundException){返回默认值(StorageFile);}
}
还请注意,我还使用了GetFileAsync
,并尝试使用uri获取种子文件(以查看是否有任何差异)。在这里,我的成功率似乎最高。这似乎每4次尝试中就有2-3次有效,但我更喜欢100%有效的东西。它只需要在启动时复制数据库一次
当它不工作时,“似乎”永远不会回来(即CopyIfNotExists
似乎永远不会完成)。问题似乎出现在CopyIfNotExists
方法中。问题在于,实际上,我的OnNavigatedTo
方法中的下一行代码是对数据库的查询,当数据库不复制时,它就会失效
任何人的见解都将不胜感激。据我所见,这里的问题是您对
async
和wait
的使用没有尽可能深入调用堆栈
在编写异步代码时,有两条一般规则需要遵循-
Foo
使用async
关键字,则调用Foo
的任何其他函数也必须使用async
关键字async void
,请改用async Task
。例外情况如下:
- 您的函数是一个事件处理程序(例如按钮按下)
- 或者您正在重写一个恰好返回
void
覆盖void OnNavigatedTo()
异步void LoadData()
异步任务CopyIfNotExists()
异步任务GetIfFileExistsAsync()
调用堆栈底部的两个方法在方法签名中使用async Task
。在调用堆栈的上面是LoadData
,它遵循上面的规则1,但违反了规则2<代码>加载数据应更改为:
公共静态异步任务LoadData()
{
等待CopyIfNotExists(dbName);
}
接下来,我们尝试使on导航,以遵循上述规则:
异步保护覆盖无效OnNavigatedTo(NavigationEventArgs e)
请注意,我们不能使用异步任务
,因为您的方法是重写。我们必须坚持使用异步void
现在您只需要将wait
添加到LoadData
调用中,因为它是一种async
方法。我们这样做是为了让您的程序在调用RefreshScenarioList
之前等待LoadData
完成:
异步保护覆盖无效OnNavigatedTo(NavigationEventArgs e)
{
//调用Dal类中的方法,以确保数据库位于正确的位置,如果不在,则复制它
等待Dal.LoadData();
RefreshScenarioList();
ScenarioList.SelectedIndex=0;//这是默认项
}
现在,您还需要确保RefreshScenarioList
的调用堆栈遵循上述异步规则
我注意到你的代码还有一件事。在Windows 8.1或更高版本中,应使用而不是GetFileAsync
:
private静态异步任务GetIfFileExistsAsync(字符串键)
{
将wait ApplicationData.Current.LocalFolder.TryGetItemAsync(key)作为存储文件返回;
}
新方法在找不到文件时返回null
。旧方法抛出一个异常。在UI线程上抛出异常可能会导致UI暂停,因此使用新方法是有利的。从我所看到的,这里的问题是使用async
和wait
在调用堆栈中的位置并没有尽可能高
在编写异步代码时,有两条一般规则需要遵循-
如果函数Foo
使用async
关键字,则调用Foo
的任何其他函数也必须使用async
关键字
切勿在函数签名中使用async void
,请改用async Task
。例外情况如下:
- 您的函数是一个事件处理程序(例如按钮按下)
- 或者您正在重写一个恰好返回
void
让我们看看调用堆栈上的方法签名<代码>打开导航