Как избавиться от FormattedText / сделать WPF отпустить файл.TTF?
В моем приложении WPF у меня есть собственная реализация Canvas, в которой я рисую некоторый текст, используя указанный файл.ttf. Файл 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
заблокировать файл шрифта (попытался закомментировать эту строку). Использование экземпляра formattedText для назначения переменных textWidth и textHeight достаточно, чтобы WPF оставил файл открытым.
Обновление: я не смог решить эту проблему, поэтому в настоящее время я использую обходной путь, который создает новый каталог временных шрифтов, если перезаписать существующий каталог не удается. Это работает, но я не очень доволен необходимостью сделать это, поэтому мне все еще интересны любые предложения, как это исправить.
1 ответ
Возможно, это каким-то образом связано с Presentation Font Cache, службой, которая работает для кеширования структур данных шрифтов, чтобы приложения WPF работали лучше... возможно, он держит файл заблокированным.
Попробуйте изменить службу Presentation Font Cache, чтобы она была остановлена и отключена. Запустите ваше приложение, затем попробуйте и посмотрите, можете ли вы удалить файл шрифта.
Отключение кэша шрифтов презентации не является долгосрочным решением, если оно действительно является причиной. Вы могли бы сойти с рук программно останавливая и перезапуская его... не уверен, как это повлияет на другие работающие приложения WPF.
Существует более точный способ узнать, кто заблокировал файл, используя инструмент, например:
Возможное решение (чтобы обойти того, кто блокирует файл) состоит в том, чтобы поместить файл.TTF в качестве ресурса в ваше приложение, и тогда вы можете позволить WPF беспокоиться о том, как управлять им и очищать его.
Ссылки:
ОБНОВИТЬ:
Вы можете создать класс-оболочку, задачей которого является удаление файла при удалении объекта или если он не может удалить файл во время удаления, поскольку файл все еще заблокирован, то он будет удален, когда сборщик мусора вызовет Финализатор.
Другая возможность заключается в использовании FileOptions.DeleteOnClose
- вам нужно посмотреть, возможно ли использовать FontFamily для файла шрифта, который вы открыли / создали и в настоящее время сохраняете дескриптор открытого файла.
Вы говорите: "Файл ttf находится во временном местоположении, которое можно удалить в более поздний момент времени".... когда вы говорите в более поздний момент времени... Я предполагаю, что это когда вы выходите из программы / процесса.... или это не тот случай?
или попробуйте TempFileCollection: