我需要"种子"我的应用程序与SQlite数据库。我在帖子How to deploy a database file with a Xamarin.form app?中使用了@Kasper建议的代码。
我的UWP代码看起来像这样。
public async Task<String> GetDBPathAndCreateIfNotExists()
{
String filename = "birdsnbflys.db3";
bool isExisting = false;
try
{
StorageFile storage = await ApplicationData.Current.LocalFolder.GetFileAsync(filename);
isExisting = true;
}
catch (Exception)
{
isExisting = false;
}
if (!isExisting)
{
StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync(filename);
await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder, filename, NameCollisionOption.ReplaceExisting);
}
return Path.Combine(ApplicationData.Current.LocalFolder.Path, filename);
}
当我在&#34;本地机器上运行时#34;它&#34;挂起/永不返回&#34;
StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync(filename);
如果我查看Package.Current.InstalledLocation文件夹,那么数据库文件就在那里。
当我在其中一个设备模拟器上运行它时,它会挂起/永远不会从&#34;
await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder, filename, NameCollisionOption.ReplaceExisting);
在这种情况下,如果我退出应用程序然后重新启动它,该文件现在位于ApplicationData.Current.LocalFolder中,以便应用程序运行。
考虑到我的应用程序的需求,我会很高兴采用同步方式来做到这一点,但它看起来并不像微软提供任何东西而是异步。
有关如何按预期工作的任何想法或建议吗?
谢谢, 戴夫
答案 0 :(得分:0)
首先,我建议您使用GetFileAsync
而不是TryGetItemAsync
。这样,您就可以避免使用try-catch块
此外,您应该在案例中使用ConfigureAwait(false)
。您不需要该方法返回同一个线程。最终,您的问题是由死锁引起的。
// The caller of this method may use ConfigureAwait(false) as well,
// depending on the call-site and result-usage.
public async Task<String> GetDBPathAndCreateIfNotExists()
{
String filename = "birdsnbflys.db3";
// Check if file exists
var file = await ApplicationData.Current.LocalFolder.TryGetItemAsync(filename).ConfigureAwait(false);
var fileExists = file != null;
// If the file doesn't exist, copy it without blocking the task
if (!fileExists)
{
var databaseFile = await Package.Current.InstalledLocation
.GetFileAsync(filename)
.ConfigureAwait(false);
await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder,
filename,
NameCollisionOption.ReplaceExisting)
.ConfigureAwait(false);
}
return Path.Combine(ApplicationData.Current.LocalFolder.Path, filename);
}
答案 1 :(得分:0)
在阅读了关于async / await的大量内容并查看各种问题和答案之后,看起来我的问题是由错误地调用GetDBPathAndCreateIfNotExists方法引起的。这是在App类的属性中完成的。
我的初始代码是:
Task<string> bnbreproTask = DependencyService.Get<IFileHelper>().GetDBPathAndCreateIfNotExists();
我发现替代它可以消除这些问题:
var dbName = Task.Run(async () => { return await DependencyService.Get<IFileHelper>()
.GetDBPathAndCreateIfNotExists(); })
.Result;
我有足够的async / await经验,每次尝试使用它时都会遇到麻烦,所以我不知道这是不是最好的解决方案。它在这种情况下确实有效。
戴夫