2015-02-23 1 views
1

Я использую этот простой шаблон для создания файла DOCX в приложении ASP.NET:Использование ошибки WordprocessingDocument: Невозможно создать семафор

var outputFileName = "creating some file name here..."; 
var outputFile = string.Format("~/App_Data/files/{0}.docx", outputFileName); 

// creating a file stream to write to 
var outputStream = new FileStream(HttpContext.Current.Server.MapPath(outputFile), FileMode.OpenOrCreate); 

// creating the default template 
using (var sr = new StreamReader(HttpContext.Current.Server.MapPath("~/some-template.docx"), Encoding.UTF8)) { 
    var l = (int)sr.BaseStream.Length; 
    var buffer = new byte[l]; 
    sr.BaseStream.Read(buffer, 0, l); 
    outputStream.Write(buffer, 0, l); 
} 

// creating the document parts 
using (WordprocessingDocument docx = WordprocessingDocument.Open(outputStream, true)) { 
    // adding parts here... 

    // adding a large amount of data in an iterator 
    foreach(var item in someList) { 
     // adding some parts... 
     outputStream.Flush(); 
    } 

    docx.Close(); 
} 

outputStream.Flush(); 
outputStream.Close(); 
outputStream.Dispose(); 

Я должен сказать, что данные я работаю, составляет около 100 000 записей из БД.

На местном уровне он работает нормально; на рабочем сервере (win 2012 R2), он отлично работает для небольших файлов; но в больших файлов (если есть слишком много записей, чтобы записать в файл), я получаю эту ошибку:

Unable to create mutex. (Exception from HRESULT: 0x80131464)

А вот трассировки стека:

at System.IO.IsolatedStorage.IsolatedStorageFile.Open(String infoFile, String syncName) at System.IO.IsolatedStorage.IsolatedStorageFile.Lock(Boolean& locked) 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.SwitchModeIfNecessary() at MS.Internal.IO.Packaging.SparseMemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) at MS.Internal.IO.Packaging.CompressEmulationStream.Write(Byte[] buffer, Int32 offset, Int32 count) at MS.Internal.IO.Packaging.CompressStream.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) at System.Xml.XmlUtf8RawTextWriter.FlushBuffer() at System.Xml.XmlUtf8RawTextWriter.RawText(Char* pSrcBegin, Char* pSrcEnd) at System.Xml.XmlUtf8RawTextWriter.RawText(String s) at System.Xml.XmlUtf8RawTextWriter.WriteStartAttribute(String prefix, String localName, String ns) at System.Xml.XmlWellFormedWriter.WriteStartAttribute(String prefix, String localName, String namespaceName) at DocumentFormat.OpenXml.OpenXmlElement.WriteAttributesTo(XmlWriter xmlWriter) at DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) at DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) at DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) at DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) at DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) at DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) at DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) at DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) at DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) at DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) at DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) at DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) at DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) at DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) at DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) at DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) at DocumentFormat.OpenXml.OpenXmlPartRootElement.WriteTo(XmlWriter xmlWriter) at DocumentFormat.OpenXml.OpenXmlPartRootElement.SaveToPart(OpenXmlPart openXmlPart) at DocumentFormat.OpenXml.OpenXmlPartRootElement.Save() at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.SavePartContents() at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.Dispose(Boolean disposing) at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.Dispose() at MyClass.GetDocx()

Вопрос заключается в том: Хотя I Я пишу файл в свою собственную папку App_Data, почему это будет IsolatedStorage? Как я могу это предотвратить?

+0

Вы видите этот вопрос? https://stackoverflow.com/questions/19465653/openxml-and-unable-to-create-mutex –

+0

@ MichałKomorowski Да, я видел это (и на самом деле много документов в googled). Мой вопрос заключается в том, что, когда я пишу docx в своей собственной папке App_Data, почему он собирается 'IsolatedStorage'? Как я могу это предотвратить? Спасибо за помощь –

ответ

2

В трассе стека вы можете найти SparseMemoryStream класс. Этот класс под капотом использует либо поток памяти, либо изолированное хранилище. Это зависит от 2 параметров, называемых Знак с низкой влажностью и Знак высокой воды. Если объем памяти составляет>Знак высокой воды, тогда используется изолированное хранилище. Как вы заметили, это становится проблемой в случае приложений на стороне сервера, работающих в IIS. К сожалению, проблема в том, что значения этих параметров жестко закодированы в классе CompressStream. Другими словами, это по дизайну.

private const long _lowWaterMark = 0x19000; // we definately would like to keep everythuing under 100 KB in memory 
private const long _highWaterMark = 0xA00000; // we would like to keep everything over 10 MB on disk 

Автор библиотеки EPPlus имел подобный problem и мне кажется, что решение было использовать не Microsoft библиотеки упаковки.

Я не знаю openxml-sdk, но, возможно, можно заменить стандартное решение для упаковки Microsoft на что-то еще.

+0

Отличный ответ. Раньше я был * глубоким читателем кода *, как вы; но, похоже, я старею;) Спасибо за помощь. –