不允许对IsolatedStorageFileStream 进行操作

发布于 2024-12-10 03:48:10 字数 3132 浏览 0 评论 0原文

我正在构建这个 WP7 应用程序,它使用视频游戏 API 来获取某人角色的统计数据(只是为了帮助学习 silverlight)。它从网络服务中获取玩家详细信息,并将其存储在手机上的独立存储中,以减轻服务器的压力。

最初我有一个类同时具有缓存写入和读取功能,但现在我不得不将其分成两个单独的类。缓存写入类目前并不重要,只要缓存读取类即可。

在第 7 行,它抛出一个异常,指出“在isolatedStorageFileStream 上不允许操作。”,但仅在第二次实例化该类期间。我已经用 debug 做了一些检查,它说该文件肯定存在,但它在第二个 using 子句之后停止。

有人可以帮我解决这个问题吗?我觉得我错过了一些非常明显的东西。

public class CacheReader
{
    public PlayerData GetPlayerData(string gamertagIn)
    {
        using (IsolatedStorageFile CachedReachData = IsolatedStorageFile.GetUserStoreForApplication())
        {
            using (IsolatedStorageFileStream stream = CachedReachData.OpenFile(gamertagIn + ".xml", FileMode.Open))
            {
                Debug.WriteLine("Data Retrieved from cache");
                XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
                PlayerData loadedPlayer = (PlayerData)serializer.Deserialize(stream);
                return loadedPlayer;
            }
        }
    }
}

[编辑1] 这是我得到的堆栈跟踪:

at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, IsolatedStorageFile isf)
   at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
   at System.IO.IsolatedStorage.IsolatedStorageFile.OpenFile(String path, FileMode mode, FileAccess access)
   at ReachPhoneApp.CacheReader.GetPlayerFromCache(String gamertagIn)
   at ReachPhoneApp.Page2.GetPlayerData()
   at ReachPhoneApp.Page2.cacheWriter_UpdateComplete()
   at ReachPhoneApp.CacheWriter.WritePlayerDataToCache(String fileNameIn, Object objectIn)
   at ReachPhoneApp.CacheWriter.client_GetGameHistoryCompleted(Object sender, GetGameHistoryCompletedEventArgs e)
   at ReachPhoneApp.ReachAPI.ReachApiSoapClient.OnGetGameHistoryCompleted(Object state)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at System.Delegate.DynamicInvokeOne(Object[] args)
   at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
   at System.Delegate.DynamicInvoke(Object[] args)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
   at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
   at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
   at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
   at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)

I'm building this WP7 app that uses a video game API to get the statistics of someone's character (just to help learn silverlight). It grabs the players details from the web service and stores them on isolated storage on the phone to relieve strain from the server.

Originally I had a class which had both the cache writing and reading function, but now i've had to seperate it out into two seperate classes. The cache writing class doesn't matter at the moment, just the cache reading class.

On line 7, it throws an exception saying "Operation not permitted on IsolatedStorageFileStream.", but only during the second time it instantiates the class. I've done some checking with debug and it says the file definately exists, but it stops after the second using clause.

Can anyone help me with this please? I feel like I'm missing something really obvious.

public class CacheReader
{
    public PlayerData GetPlayerData(string gamertagIn)
    {
        using (IsolatedStorageFile CachedReachData = IsolatedStorageFile.GetUserStoreForApplication())
        {
            using (IsolatedStorageFileStream stream = CachedReachData.OpenFile(gamertagIn + ".xml", FileMode.Open))
            {
                Debug.WriteLine("Data Retrieved from cache");
                XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
                PlayerData loadedPlayer = (PlayerData)serializer.Deserialize(stream);
                return loadedPlayer;
            }
        }
    }
}

[EDIT 1]
This is the stack trace i get:

at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, IsolatedStorageFile isf)
   at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
   at System.IO.IsolatedStorage.IsolatedStorageFile.OpenFile(String path, FileMode mode, FileAccess access)
   at ReachPhoneApp.CacheReader.GetPlayerFromCache(String gamertagIn)
   at ReachPhoneApp.Page2.GetPlayerData()
   at ReachPhoneApp.Page2.cacheWriter_UpdateComplete()
   at ReachPhoneApp.CacheWriter.WritePlayerDataToCache(String fileNameIn, Object objectIn)
   at ReachPhoneApp.CacheWriter.client_GetGameHistoryCompleted(Object sender, GetGameHistoryCompletedEventArgs e)
   at ReachPhoneApp.ReachAPI.ReachApiSoapClient.OnGetGameHistoryCompleted(Object state)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at System.Delegate.DynamicInvokeOne(Object[] args)
   at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
   at System.Delegate.DynamicInvoke(Object[] args)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
   at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
   at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
   at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
   at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

北城孤痞 2024-12-17 03:48:10

检查是否有两个线程同时访问IsolatedStorage(即在VS Debug.View.Threads 中并验证在异常发生时您没有通过相同IsoStore 代码的多个路径)。

这种情况每隔几天就会在我的 WP7 代码中发生一次,而且很难找到,因为它似乎只在未连接到调试器时才会发生。

Check that you don't somehow have two threads accessing IsolatedStorage at the same time (ie. in VS Debug.View.Threads and verify that at the time of the exception you don't have multiple paths through the same IsoStore code).

This happened in my WP7 code once every few days and was tricky to find, as it seemed to occur only when not connectected to the debugger.

原来分手还会想你 2024-12-17 03:48:10

您需要

stream.Close();

先致电:

return loadedPlayer;

You need to call:

stream.Close();

before

return loadedPlayer;
北座城市 2024-12-17 03:48:10

我认为问题在于您没有通过指定 System.IO.FileShare.ReadWrite 或您需要的任何访问权限作为 OpenFile 的最后一个参数来指定多个线程可以同时读/写。

请参阅 Microsoft 论坛上的讨论

I think the problem is that you didn't specify that multiple threads could read/write at the same time by specifying a System.IO.FileShare.ReadWrite or whatever access you need as the last parameter of OpenFile.

See the discussion here on the Microsoft Forums.

梦年海沫深 2024-12-17 03:48:10

我也遇到了这个问题,但原因与上面提到的完全不同。我没有创建要保存到的目录。

private void SaveStringDataToStorage(string sDirectory, string sFileName, string sFileContent)
    {
        string sPath;
        //            
        using (IsolatedStorageFile oFile = solatedStorageFile.GetUserStoreForApplication())
        {
            if (!oFile.DirectoryExists(sDirectory))
                oFile.CreateDirectory(sDirectory);
            //
            sPath = Path.Combine(sDirectory, sFileName);
            //
            using (var oWriter = new StreamWriter(new IsolatedStorageFileStream(sPath, FileMode.Create, oFile)))
                oWriter.Write(sFileContent);
        }
    }

如果您遇到与我相同的问题,则可以使用此代码,而且它非常简单,因此您可以根据需要进行调整。在遇到问题之前我就使用过这段代码,但我忘记了 ! 所以目录从未创建过哈哈。只是典型的。希望这有帮助:)

编辑

仔细查看原来的问题,可能是该文件不存在。我认为,无论您是在读取还是写入,在尝试访问任一位置之前,最好先执行 IsolatedStorageFile.DirectoryExists()IsolatedStorageFile.FileExists() 操作。

I ran into this issue as well, but for completely different reasons as mentioned above. I hadn't created the directory that I was saving into.

private void SaveStringDataToStorage(string sDirectory, string sFileName, string sFileContent)
    {
        string sPath;
        //            
        using (IsolatedStorageFile oFile = solatedStorageFile.GetUserStoreForApplication())
        {
            if (!oFile.DirectoryExists(sDirectory))
                oFile.CreateDirectory(sDirectory);
            //
            sPath = Path.Combine(sDirectory, sFileName);
            //
            using (var oWriter = new StreamWriter(new IsolatedStorageFileStream(sPath, FileMode.Create, oFile)))
                oWriter.Write(sFileContent);
        }
    }

Using this code will work if you had the same problem as me, plus it's pretty simple so you can adapt it to whatever you need. I was using this code before I had issues, but I'd forgotten the ! so the directory was never created haha. Just typical. Hope this helps :)

EDIT

Looking closer at the original question, it may be that the file didn't exist. I think it's always best to do IsolatedStorageFile.DirectoryExists() and IsolatedStorageFile.FileExists() before trying to access either location, whether you are reading or writing.

浮华 2024-12-17 03:48:10

默认情况下,当您使用 IsolatedStorageFile.OpenFile("filename", FileMode.Open) 时,您的文件将被该线程锁定,并且在第一个线程关闭该文件之前,其他线程都无法访问该文件。但是,如果您想在多个线程中共享文件仅用于读取目的,那么我建议您使用以下重写

IsolatedStorageFile.OpenFile("filename", FileMode.Open, FileAccess.Read, FileShare.Read)

查看详细信息 此处

By default when you use IsolatedStorageFile.OpenFile("filename", FileMode.Open) your file gets locked by this thread and no other thread would be able to access this file until 1st thread close it. But if you like to share your file in multiple threads for read purpose only then I would recommend you to use following override

IsolatedStorageFile.OpenFile("filename", FileMode.Open, FileAccess.Read, FileShare.Read)

see details here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文