我有一個程序,基本上從數據庫中提取數據,將其緩存到一個文件,然後將該數據導出爲多種格式(Excel,Excel 2003,CSV)。我使用OpenXML SDK 2.0來完成Excel工作。這些導出過程並行運行(使用Parallel.ForEach
),並且數據量可能非常大 - 例如一些CSV是800MB。在這些較大的導出期間,我注意到XML文檔的寫入會掛起。例如,如果我有8個並行輸出,在某些時候,他們只會「暫停」。他們都流連相同點:OpenXML在寫元素時掛起
//this.Writer is an OpenXmlWriter which was created from a WorksheetPart.
this.Writer.WriteElement(new Cell()
{
CellValue = new CellValue(value),
DataType = CellValues.String
});
發生這種情況時,我暫停(在這種情況下VS2013)調試器,發現所有線程的代碼相同的部分周圍阻塞 - 有些是在深一點OpenXML SDK - 但它們都是來自OpenXmlWriter.WriteElement
的調用。
我使用JustDecompile通過源挖掘,但沒有找到任何答案。看來有一箇中間流正在使用,正在寫入孤立的存儲,這是由於某種原因,阻塞。其中每一個的基礎流是FileStream
。
在這裏是表示所有的屏幕截圖(8在這種情況下)在阻斷或OpenXmlWriter.WriteElement
方法內並行任務:爲這些掛起線程之一
整個疊層 - 與註釋。
WindowsBase.dll!MS.Internal.IO.Packaging.PackagingUtilities.CreateUserScopedIsolatedStorageFileStreamWithRandomName Normal
WindowsBase.dll!MS.Internal.IO.Packaging.PackagingUtilities.CreateUserScopedIsolatedStorageFileStreamWithRandomName(int retryCount, out string fileName)
WindowsBase.dll!MS.Internal.IO.Packaging.SparseMemoryStream.EnsureIsolatedStoreStream()
//---> Why are we writing to isolated storage at all?
WindowsBase.dll!MS.Internal.IO.Packaging.SparseMemoryStream.SwitchModeIfNecessary()
WindowsBase.dll!MS.Internal.IO.Zip.ZipIOFileItemStream.Write(byte[] buffer, int offset, int count)
System.dll!System.IO.Compression.DeflateStream.WriteDeflaterOutput(bool isAsync)
System.dll!System.IO.Compression.DeflateStream.Write(byte[] array, int offset, int count)
WindowsBase.dll!MS.Internal.IO.Packaging.CompressStream.Write(byte[] buffer, int offset, int count)
WindowsBase.dll!MS.Internal.IO.Zip.ProgressiveCrcCalculatingStream.Write(byte[] buffer, int offset, int count)
WindowsBase.dll!MS.Internal.IO.Zip.ZipIOModeEnforcingStream.Write(byte[] buffer, int offset, int count)
System.Xml.dll!System.Xml.XmlUtf8RawTextWriter.FlushBuffer()
System.Xml.dll!System.Xml.XmlUtf8RawTextWriter.WriteAttributeTextBlock(char* pSrc, char* pSrcEnd)
System.Xml.dll!System.Xml.XmlUtf8RawTextWriter.WriteString(string text)
System.Xml.dll!System.Xml.XmlWellFormedWriter.WriteString(string text)
DocumentFormat.OpenXml.dll!DocumentFormat.OpenXml.OpenXmlElement.WriteAttributesTo(System.Xml.XmlWriter xmlWriter)
DocumentFormat.OpenXml.dll!DocumentFormat.OpenXml.OpenXmlElement.WriteTo(System.Xml.XmlWriter xmlWriter)
DocumentFormat.OpenXml.dll!DocumentFormat.OpenXml.OpenXmlPartWriter.WriteElement(DocumentFormat.OpenXml.OpenXmlElement elementObject)
//---> At this point, threads seem to be blocking.
MyProject.Common.dll!MyProject.Common.Export.ExcelWriter.WriteLine(string[] values) Line 117
還有一兩件事值得一提的是,雖然有8件事(在這種情況下)在一次被出口,每一個人出口以串聯方式寫入多個文件。例如,給定的導出可能包含150個要導出到的基礎文件 - 輸入數據是分段的,只有一部分寫入每個文件。基本上,我緩存來自數據庫的批量數據,然後讀取一行並將其推送(逐個串行)到應包含此數據的流。問題是,如果有8個出口商正在運行,那麼可能有1000個文件也被寫入,但在任何給定時間只有8個文件正在寫入。
你有沒有發現這個問題的解決?我現在遇到同樣的問題。 – syazdani
不幸的是,沒有。我轉向其他事情。但這仍然是我真正需要解決的問題! –