我正在从控制台应用程序打印报告。我开始使用微软规定的方式(http://msdn.microsoft.com/en-us/library/ms252172(v=vs.100).aspx)。在这种技术中,人们会呈现这样的报告:
report.Render("Image", deviceInfo, CreateStream, out warnings);
CreateStream 是一个函数的回调:
private Stream CreateStream(string name, string fileNameExtension,
Encoding encoding, string mimeType, bool willSeek)
{
Stream stream = new FileStream(name + "." + fileNameExtension,
FileMode.Create);
m_streams.Add(stream);
return stream;
}
这个想法是您呈现您想要归档的报告,让流打开并收集在一个数组中。然后,一旦它们全部渲染完毕,您就可以遍历该数组,使用这些打开的流将文件内容发送到打印机。
这适用于一些报告,但就我而言,我打印了大约 1500 个单页报告。显然,我不能在不严重降低性能的情况下让所有这些流挂起。所以,我修改了一些东西。我创建了一个在 CreateStream 回调中使用的类级流对象 (RenderStream),并将文件名保存在一个集合中。
RenderStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read);
RenderedFileList.Add(fileName);
然后我在 Report.Render() 函数返回后 RenderStream.Dispose() 。
这样我的流就保持关闭和处理。在我所有的导出完成后,当我去打印时,在 PrintPage 事件中我这样做:
private void PrintPage(object sender, PrintPageEventArgs ev)
{
using (Stream stream = new FileStream(RenderedFileList[fileCounter], FileMode.Open, FileAccess.Read, FileShare.Read))
{
Metafile pageImage = new Metafile(stream);
ev.Graphics.DrawImage(pageImage, ev.PageBounds);
}
}
现在,问题出在哪里。虽然我通常可以毫无问题地打开这些渲染文件的流,但我在打印时访问这些文件的尝试中约有 5% 返回异常,报告该文件不可访问,因为它已被另一个进程打开。即使先前的流已被处理。
我能做些什么来解决这个问题?