4

私のWPFアプリではFlowDocument、XAMLマークアップを文字列として作成し、を使用XamlReader.Parseして文字列をFlowDocumentオブジェクトに変換し、それをXPSドキュメントファイルに保存して作成しています。できます。

ドキュメントに画像を含める必要があったため、これを実現するには、画像を作成して一時ファイルとして一時ディレクトリに保存し、FlowDocumentXAMLの絶対パスで参照します。これも機能します。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作成コードにファイルロックの原因となるバグがあると思われるかもしれません。

他に試すことができるものはありますか?または、コードを介してファイルロックを削除する方法はありますか?

4

1 に答える 1

2

代わりに、次のように xaml を変更できます。

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

Xaml Builder が画像ファイルをロードする方法を指定するために、パラメーターを操作できるようにしCacheOptionます。これは、デフォルト値がロックを保持しているように見えるためです (GC がその作業を行うのを待っているようです)。

SOに関する関連する質問は次のとおりです。WPFがメモリから大きなBitmapSourceを解放することを確認するにはどうすればよいですか?

于 2012-05-23T08:49:49.567 に答える