2

私の WPF アプリケーションには、指定した .ttf ファイルを使用してテキストを描画するカスタム Canvas 実装があります。ttf ファイルは、後で削除できる一時的な場所に存在します。私の問題は、テキストがキャンバスにレンダリングされると、ttf ファイルが開いたままのように見え、アプリケーションが閉じられるまで削除できないことです。フォントファイルを開いたままにする FormattedText インスタンスのようです。FormattedText を「破棄」する方法を知っている人はいますか、またはレンダリング後にフォント ファイルが閉じていることを確認する方法はありますか?

私のテキスト描画コード:

public class MyCanvas : System.Windows.Controls.Canvas
{
    protected override void OnRender(DrawingContext dc)
    {
        base.OnRender(dc);

        // Some other drawing stuff...

        FontFamily fontFamily = new FontFamily(fontUri);
        Typeface typeFace = new Typeface(fontFamily, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
        FormattedText formattedText = new FormattedText(chars, System.Globalization.CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeFace, text.FontHeight, new SolidColorBrush(color));
        dc.DrawText(formattedText, new Point(text.X + offsetX, text.Y + offsetY));
        int textWidth = (int) formattedText.Width;
        int textHeight = (int)formattedText.Height;

        // Drawing continues...
    }
}

注:フォントファイルをロックするために呼び出す必要さえないようDrawTextです(その行をコメントアウトしようとしました)。WPF がファイルを開いたままにするには、formattedText インスタンスを使用して textWidth 変数と textHeight 変数を割り当てるだけで十分です。

更新: この問題を解決できなかったので、現在、既存の一時フォント ディレクトリの上書きに失敗した場合に新しい一時フォント ディレクトリを作成する回避策を使用しています。それは機能しますが、このようにしなければならないことにあまり満足していないので、これを修正する方法の提案にまだ興味があります.

4

1 に答える 1

1

おそらく、WPFアプリのパフォーマンスを向上させるためにフォントデータ構造をキャッシュするために実行されるサービスであるPresentation Font Cacheに何らかの形で関連している可能性があります....ファイルをロックしたままにしている可能性があります。

プレゼンテーション フォント キャッシュ サービスを停止して無効にするように変更してみてください。アプリケーションを実行してから、フォント ファイルを削除できるかどうかを確認してください。

プレゼンテーション フォント キャッシュを無効にすることは、それが実際に原因である場合、長期的な解決策ではありません。プログラムで停止して再起動するとうまくいくかもしれません...それが他の実行中のWPFアプリケーションにどのように影響するかはわかりません。

次のようなツールを使用して、誰がファイルをロックしているかを確認するより確実な方法があります。

(ファイルをロックしている人を回避するための) 考えられる解決策は、.TTF ファイルをリソースとしてアプリケーションに配置することです。そうすれば、WPF にファイルの管理方法とクリーンアップ方法を任せることができます。

リンク:

アップデート:

オブジェクトが破棄されるときにファイルを削除するジョブを持つラッパー クラスを作成できます。または、ファイルがまだロックされているために破棄時にファイルを削除できない場合は、ガベージ コレクターがファイナライザーを呼び出すときに削除されます。

もう 1 つのFileOptions.DeleteOnClose可能性は使用することです。開いた/作成したフォント ファイルで FontFamily を使用でき、現在開いているファイル ハンドルを維持できるかどうかを確認する必要があります。

「ttfファイルは一時的な場所にあり、後で削除できます。」...後で言うと...プログラム/プロセスを終了したときだと思います……そうでもないのか。

またはTempFileCollectionを試してください:

于 2012-07-24T21:32:55.900 に答える