在WPF中创建XPS – 使用的图像文件被锁定,直到我的应用程序退出

在我的
WPF应用程序中,我通过将XAML标记构建为字符串来创建FlowDocument,然后使用XamlReader.Parse将字符串转换为FlowDocument对象,然后将其保存到XPS文档文件中.有用.

我需要在我的文档中包含一个图像,因此为了实现这一点,我创建并将图像保存为temp目录中的临时文件,然后在FlowDocument的XAML中使用绝对路径引用它.这也有效 – 在XPS文档创建过程中,图像实际上嵌入到XPS文档中,这很棒.

但问题是,我的应用程序会保留此图像上的文件锁定,直到该应用程序退出.

我正在清理所有资源.我生成的XPS文件没有文件锁定 – 只是图像文件.如果我注释掉我创建XPS文件的代码部分,那么图像文件不会被锁定.

我的代码(我在.NET 4 CP上):

var xamlBuilder = new StringBuilder();

// many lines of code like this
xamlBuilder.Append(...);

// create and save image file
// THE IMAGE AT THE PATH imageFilePath IS GETTING LOCKED
// AFTER CREATING THE XPS FILE
var fileName = string.Concat(Guid.NewGuid().ToString(), ".png");
var imageFilePath = string.Format("{0}{1}", Path.GetTempPath(), fileName);
using (var stream = new FileStream(imageFilePath, FileMode.Create)) {
  var encoder = new PngBitmapEncoder();
  using (var ms = new MemoryStream(myBinaryImageData)) {
    encoder.Frames.Add(BitmapFrame.Create(ms));
    encoder.Save(stream);
  }
  stream.Close();
}

// add the image to the document by absolute path
xamlBuilder.AppendFormat("<Paragraph><Image Source=\"{0}\" ...", imageFilePath);

// more lines like this
xamlBuilder.Append(...);

// create a FlowDocument from the built string
var document = (FlowDocument) XamlReader.Parse(xamlBuilder.ToString());

// set document settings
document.PageWidth = ...;
...

// save to XPS file
// THE XPS FILE IS NOT LOCKED. IF I LEAVE OUT THIS CODE
// AND DO NOT CREATE THE XPS FILE, THEN THE IMAGE IS NOT LOCKED AT ALL
using (var xpsDocument = new XpsDocument(filePath, FileAccess.ReadWrite)) {
  var documentWriter = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
  documentWriter.Write(((IDocumentPaginatorSource) document).DocumentPaginator);
  xpsDocument.Close();
}

(实际上,它是临时目录中动态生成的图像这一事实无关紧要 – 如果我在我的机器上的任何图像文件的路径中进行硬编码,就会出现此问题 – 它将被锁定.)

有人会认为XPS创建代码中存在导致文件锁定的错误.

我还能尝试别的吗?或者通过代码删除文件锁的方法?

最佳答案 你可以这样改变你的xaml:

<Image>
    <Image.Source>
        <BitmapImage CacheOption="None" UriSource="your path" />
    </Image.Source>
</Image>

能够使用CacheOption参数来指定Xaml Builder应该如何加载图像文件,因为默认值似乎是保持对它的锁定(等待GC看起来如此工作).

以下是关于SO:How do you make sure WPF releases large BitmapSource from Memory?的一些相关问题

点赞