IsolatedStorageException有时会在磁盘已满的情况下出现?

时间:2013-03-29 15:37:46

标签: c# file-io windows-phone-8 windows-phone isolatedstorage

我正在设计一个API。目前我正在尝试安全地处理磁盘空间不足的情况。基本上,我们有一系列文件包含一些数据。当磁盘已满时,当我们去写另一个数据文件时,它当然会抛出一个错误。此时,我们删除单个文件(从最旧到最新循环文件列表,并在成功删除文件后重试)。然后,我们重试写文件。重复该过程,直到写入文件没有错误。

现在有趣的部分。所有这些都同时发生。比如,在某些时候有8个线程同时执行此操作。这使事情变得更加有趣,并导致一个奇怪的错误。

这是代码

    public void Save(string text, string id)
    {
        using (var store = IsolatedStorageFile.GetUserStoreForApplication())
        {
            var existing = store.GetFileNames(string.Format(Prefix + "/*-{0}.dat", id));
            if (existing.Any()) return; //it already is saved

            string name = string.Format(Prefix + "/{0}-{1}.dat", DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff"), id);
        tryagain:
            bool doover=false;
            try
            {
                AttemptFileWrite(store, name, text);
            }
            catch (IOException)
            {
                doover = true;
            }
            catch (IsolatedStorageException) //THIS LINE
            {
                doover = true;
            }
            if (doover)
            {
                Attempt(() => store.DeleteFile(name)); //because apparently this can also fail. 
                var files = store.GetFileNames(Path.Combine(Prefix, "*.dat"));
                foreach (var file in files.OrderBy(x=>x))
                {
                    try
                    {
                        store.DeleteFile(Path.Combine(Prefix, file));
                    }
                    catch
                    {
                        continue;
                    }
                    break;
                }
                goto tryagain; //prepare the velociraptor shield!
            }
        }
    }

    void AttemptFileWrite(IsolatedStorageFile store, string name, string text)
    {
        using (var file = store.OpenFile(
            name,
            FileMode.Create,
            FileAccess.ReadWrite,
            FileShare.None | FileShare.Delete
            ))
        {
            using (var writer = new StreamWriter(file))
            {
                writer.Write(text);
                writer.Flush();
                writer.Close();
            }
            file.Close();
        }
    }

    static void Attempt(Action func)
    {
        try
        {
            func();
        }
        catch
        {
        }
    }
    static T Attempt<T>(Func<T> func)
    {
        try
        {
            return func();
        }
        catch
        {
        }
        return default(T);
    }
    public string GetSaved()
    {

        string content=null;
        using (var store = IsolatedStorageFile.GetUserStoreForApplication())
        {
            var files = store.GetFileNames(Path.Combine(Prefix,"*.dat")).OrderBy(x => x);

            if (!files.Any()) return new MessageBatch();
            foreach (var filename in files)
            {
                IsolatedStorageFileStream file=null;
                try
                {
                    file = Attempt(() =>
                        store.OpenFile(Path.Combine(Prefix, filename), FileMode.Open, FileAccess.ReadWrite, FileShare.None | FileShare.Delete));
                    if (file == null)
                    {
                        continue; //couldn't open. assume locked or some such
                    }
                    file.Seek(0L, SeekOrigin.Begin);
                    using (var reader = new StreamReader(file))
                    {
                        content = reader.ReadToEnd();
                    }
                    //take note here. We delete the file, while we still have it open!
                    //This is done because having the file open prevents other readers, but if we close it first,
                    //then there is a race condition that right after closing the stream, another reader could pick it up and 
                    //open exclusively. It looks weird, but it's right. Trust me. 
                    store.DeleteFile(Path.Combine(Prefix, filename));
                    if (!string.IsNullOrEmpty(content))
                    {
                        break;
                    }
                }
                finally
                {
                    if (file != null) file.Close();
                }
            }
        }
        return content;
    }

在标记为此线的线路上,正是我所说的。在进行AttemptFileWrite时,我可以查看store.AvailableSpace并看到有足够的空间来容纳数据,但是在尝试打开文件时,会抛出此IsolatedStorageException,其描述为Operation Not Permitted。除了这个奇怪的情况,在所有其他情况下,它只是抛出IOException,并显示有关磁盘已满的消息

我想知道我是否有一些奇怪的竞争条件,或者如果这是一个错误我只需要处理或什么?

为什么会出现此错误?

0 个答案:

没有答案