必须为此操作打开存储 - System.IO.Packaging.Package

时间:2016-03-10 17:10:53

标签: c# isolatedstorage system.io.packaging

我正在使用System.IO.Packaing.Package类来压缩文件。在读取和保存文件的同时,可以让我的应用程序的多个实例同时运行。当处理小文件时似乎都很好,但是当涉及大文件时,如果同时保存了应用程序的两个实例,则会出现一个异常消息,对于此操作,Store必须打开,并且堆栈跟踪如下所示。

根据我的理解,当使用文件包< 10mb时,数据存储在一些内存流中,但当内部> 10mb时,将切换到IsolatedStorage。考虑到这一点,我能够发现,即使这些是多个实例运行,它们都会解决相同的孤立存储位置,我相信这就是问题所在。我能够找到一个黑客来强制每个实例解决使用以下代码到不同的位置:

var rootDirUserField= typeof(IsolatedStorageFile).GetField("s_RootDirUser", BindingFlags.NonPublic | BindingFlags.Static);
rootDirUserField.SetValue(null, "<unique location in isolated storage>");

虽然这让问题消失了但我不喜欢它。请帮助弄清楚如何优雅地解决这个问题。在进一步的研究中,我发现IsolatedStorage甚至不打算用于多个线程,这让我想知道为什么它在处理包时是一个选项。

   at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, IsolatedStorageFile isf)
   at MS.Internal.IO.Packaging.PackagingUtilities.SafeIsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, ReliableIsolatedStorageFileFolder folder)
   at MS.Internal.IO.Packaging.PackagingUtilities.CreateUserScopedIsolatedStorageFileStreamWithRandomName(Int32 retryCount, String& fileName)
   at MS.Internal.IO.Packaging.SparseMemoryStream.EnsureIsolatedStoreStream()
   at MS.Internal.IO.Packaging.SparseMemoryStream.SwitchModeIfNecessary()
   at MS.Internal.IO.Packaging.SparseMemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at MS.Internal.IO.Zip.ZipIOFileItemStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at MS.Internal.IO.Zip.ProgressiveCrcCalculatingStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at MS.Internal.IO.Zip.ZipIOModeEnforcingStream.Write(Byte[] buffer, Int32 offset, Int32 count)

更新

此外,可能会遇到问题,因为要访问IsolatedStorage,您的代码必须具有所有必需的本机平台操作系统权限,如果不是,则无法创建IsolatedStorage流。

更新2

发布了针对此问题的Windows 8.1和Windows Server 2012 R2上的.NET Framework 4.5,4.5.1和4.5.2的hotfix。 Eric White还编写了一个System.IO.Packaging的新实现,不使用独立存储,这实际上将添加到COREFX中。他的实施可用here

与Microsoft相关的System.IO.Packaging可能出现的其他问题如下:

在单独的线程上使用大型包时可能会发生死锁。 System.IO.Packaging对大于10兆字节(MB)的程序包使用IsolatedStorage。当两个或多个线程使用大型软件包时,即使软件包是独立的,也可能发生死锁。死锁涉及两个线程。一个在IsolatedStorageFile.Lock中等待,而另一个在IsoloatedStorageFile类的另一个方法中等待。通过向System.IO.Packaging添加同步来解决此问题,以避免IsolatedStorageFile中的问题。 从在不同线程上打开的包中检索PackageProperties时可能会发生异常,即使这些包是独立的。由此产生的最常见的调用堆栈如下:

System.Xml.XmlException: Unrecognized root element in Core Properties part. Line 2, position 2.     at
MS.Internal.IO.Packaging.PartBasedPackageProperties.ParseCorePropertyPart(PackagePart part)     at
System.IO.Packaging.Package.get_PackageProperties()
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.  Parameter name: id     at
MS.Internal.IO.Packaging.PartBasedPackageProperties.ParseCorePropertyPart(PackagePart part)     at
System.IO.Packaging.Package.get_PackageProperties()

此问题是由共享内部资源上的争用引起的,并通过为每个程序包提供该资源的副本来解决。

0 个答案:

没有答案