2017-09-04 14 views
2

私のアプリケーションにSQliteデータベースを「シード」する必要があります。ポストHow to deploy a database file with a Xamarin.form app?の@Kasperのようにコードを使用しました。Package.Current.InstalledLocation.GetFileAsyncとStorageFile.CopyAsyncが期待通りに機能しない

私のコードは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); 
    } 

私は、「ローカルマシン」その上で、これを実行すると、私はPackage.Current.InstalledLocationフォルダを見れば、データベースファイルがある

StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync(filename); 

「ハング/から返すことはありません」。

私はデバイスエミュレータの一つでこれを実行すると、私はアプリを終了し、ファイルがApplicationData.Currentに今あることを再起動した場合、それはこの場合

await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder, filename, NameCollisionOption.ReplaceExisting); 

「ハング/から返すことはありません」 .LocalFolderので、アプリケーションが実行されます。

私のアプリの必要性を考えれば、これを同期させる方法はうれしいですが、Microsoftが非同期以外のものを提供しているようには見えません。

これを期待どおりにする方法についての考えや提案はありますか?

おかげで、すべての デイブ

+0

**非同期**は、UWPアプリケーションで行う方法です。 synchrone APIがリリースされることを期待しないでください。 – Herdo

答えて

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); 
} 
+0

自分のコードを自分のメソッドにコピーしました。その結果、どこでも.ConfigureAwaitが使用されますが、私は次のエラーを受け取ります。エラー\t CS1061 \t 'IAsyncOperation 'に 'ConfigureAwait'の定義が含まれておらず、 'IAsyncOperation 'タイプの最初の引数を受け入れる拡張メソッド 'ConfigureAwait'が見つかりませんでした(usingディレクティブまたはアセンブリ参照?) – DaveS

0

が待っていますし、私の問題が誤ってGetDBPathAndCreateIfNotExistsメソッドを呼び出すことによって引き起こされたように見える様々な質問と回答を見ています。これはAppクラスのプロパティで行われています。私は問題を解消すること、これを置き換えるために見つけたもの

Task<string> bnbreproTask = DependencyService.Get<IFileHelper>().GetDBPathAndCreateIfNotExists(); 

は次のとおりです:

私の最初のコードは、このでした

var dbName = Task.Run(async() => { return await DependencyService.Get<IFileHelper>() 
        .GetDBPathAndCreateIfNotExists(); }) 
        .Result; 

私は/非同期でちょうど十分な経験を持っているトラブルに自分自身を取得するために待っています私はそれを使用しようとするたびに、これが最善の解決策であるかどうかわかりません。このインスタンスでは動作します。

デーブ

関連する問題