最初にデータベースを作成し、そこにデータを保存するアプリを作成しました。ユーザーがリセットボタンをクリックしたときにこのデータベースとそのファイルを削除したいのですが、「これは別のプロセスで使用されています」というエラーが表示されます。リセットボタンをクリックしたときにデータベースを削除して再作成したい。何か案は?
1 に答える
これの最も一般的な原因は、Windows Phone の分離ストレージとやり取りするスレッドの安全でない性質によるものです。データベースをどのように実装するかに関係なく (ファイルであれ、一連のファイルであれ)、あるレベルで分離ストレージとやり取りしています。
先に進む前に、この分離ストレージの概要を読んで理解することを強くお勧めします。
あなたはコメントしています:
これは別のプロセスで使用されています
データベース関連の処理にサードパーティのライブラリを使用していると思われます。この例外/エラーは、ライブラリ自体が分離ストレージにアクセスできない場合にスローされます。データベースをどのように実装しているかを正確に知らなければ、状況を正確に説明することは困難です。
"IsolatedStorage を再作成" することはありません。Isolated Storage は、アプリケーションがアクセスできるディスク領域のコレクションを定義するために使用される用語です。フォルダと同じように、このディスク領域にはルートがあり、作成したファイルのみが含まれます。
分離ストレージにアクセスする際のスレッド例外を回避するには、次のように C# でusingキーワードを使用してください。
namespace IsolatedStorageExample
{
public class ISOAccess
{
// This example method will read a file inside your Isolated Storage.
public static String ReadFile(string filename)
{
string fileContents = "";
// Ideally, you should enclose this entire next section in a try/catch block since
// if there is anything wrong with below, it will crash your app.
//
// This line returns the "handle" to your Isolated Storage. The phone considers the
// entire isolated storage folder as a single "file", which is why it can be a
// little bit of a confusing name.
using(IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForAppliaction())
{
// If the file does not exist, return an empty string
if(file.Exists(filename))
{
// Obtain a stream to the file
using(IsolatedStorageFileStream stream = File.OpenFile(filename, FileMode.Open)
{
// Open a stream reader to actually read the file.
using(StreamReader reader = new StreamReader(stream))
{
fileContents = reader.ReadToEnd();
}
}
}
}
return fileContents;
}
}
}
これは、スレッドセーフの問題を解決するのに役立ちます。やりたいことに対してより具体的に役立つようにするには、次のメソッドを見てください (これを上記のクラスに追加できます)。
// BE VERY CAREFUL, running this method will delete *all* the files in isolated storage... ALL OF THEM
public static void ClearAllIsolatedStorage()
{
// get the handle to isolated storage
using(IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
{
// Get a list of all the folders in the root directory
Queue<String> rootFolders = new Queue<String>(file.GetDirectoryNames());
// For each folder...
while(0 != rootFolders.Count)
{
string folderName = rootFolders.Dequeue();
// First, recursively delete all the files and folders inside the given folder.
// This is required, because you cannot delete a non-empty directory
DeleteFilesInFolderRecursively(file, folderName);
// Now that all of it's contents have been deleted, you can delete the directory
// itsself.
file.DeleteDirectory(rootFolders.Dequeue());
}
// And now we delete all the files in the root directory
Queue<String> rootFiles = new Queue<String>(file.GetFileNames());
while(0 != rootFiles.Count)
file.DeleteFile(rootFiles.Dequeue());
}
}
private static void DeleteFilesInFolderRecursively(IsolatedStorageFile iso, string directory)
{
// get the folders that are inside this folder
Queue<string> enclosedDirectories = new Queue<string>(iso.GetDirectoryNames(directory));
// loop through all the folders inside this folder, and recurse on all of them
while(0 != enclosedDirectories.Count)
{
string nextFolderPath = Path.Combine(directory, enclosedDirectories.Dequeue());
DeleteFilesInFolderRecursively(nextFolderPath);
}
// This string will allow you to see all the files in this folder.
string fileSearch = Path.Combine(directory, "*");
// Getting the files in this folder
Queue<string> filesInDirectory = iso.GetFileNames(fileSearch);
// Finally, deleting all the files in this folder
while(0 != filesInDirectory.Count)
{
iso.DeleteFile(filesInDirectory.Dequeue());
}
}
私が強くお勧めするもう 1 つのことは、ここで説明されているように、「マルチスレッド シングルトン パターン」を使用して IsolatedStorage にアクセスするクラスを実装することです。
お役に立てば幸いです。コードは「現状のまま」提供されます。コンパイルはしていませんが、一般的な概念はすべてそこにあるので、何か問題がある場合は、MSDN ドキュメントを読んで、私がどこを間違えたのかを確認してください。しかし、これのほとんどは私の機能的なコードからコピーされたものであるため、ほとんど熱狂することなく適切に動作するはずです。