我正在构建这个WP7应用程序,该应用程序使用视频游戏API来获取某人角色的统计信息(仅用于帮助学习Silverlight)。它从Web服务中获取玩家详细信息,并将其存储在手机上的隔离存储中,以减轻服务器的压力。
最初我有一个同时具有缓存写入和读取功能的类,但现在我必须将它分成两个单独的类。缓存编写类目前无关紧要,只是缓存读取类。
在第7行,它抛出一个异常,说“在IsolatedStorageFileStream上不允许操作。”,但仅在第二次实例化类时。我已经完成了一些调试,它说文件肯定存在,但它在第二个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)
答案 0 :(得分:5)
检查你是否有两个线程同时访问IsolatedStorage(即在VS Debug.View.Threads中并验证在异常时你没有多条路径通过相同的IsoStore代码)。
这种情况每隔几天发生在我的WP7代码中,并且很难找到,因为它似乎只是在未连接到调试器时才会发生。
答案 1 :(得分:1)
您需要致电:
stream.Close();
前
return loadedPlayer;
答案 2 :(得分:1)
我认为问题在于您没有通过指定System.IO.FileShare.ReadWrite或者您需要的任何访问权限来指定多个线程可以同时读/写。作为OpenFile的最后一个参数。
Microsoft论坛上的答案 3 :(得分:1)
我也遇到了这个问题,但出于完全不同的原因,如上所述。我没有创建我保存的目录。
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()
,无论您是在阅读还是写作。
答案 4 :(得分:0)
默认情况下,当您使用IsolatedStorageFile.OpenFile("filename", FileMode.Open)
时,您的文件被此线程锁定,并且在第一个线程关闭之前,没有其他线程可以访问此文件。但是,如果您只想在多个线程中共享文件以供阅读,那么我建议您使用以下覆盖
IsolatedStorageFile.OpenFile("filename", FileMode.Open, FileAccess.Read, FileShare.Read)
查看详情here