Другой вариант - использовать пакет showtext
, который поддерживает больше типов шрифтов (TrueType, OpenType, Type 1, веб-шрифты и т. д.) и больше графических устройств и избегает использования внешнего программного обеспечения, такого как как Ghostscript.
# install.packages('showtext', dependencies = TRUE)
library(showtext)
### Import Google Fonts
# https://fonts.google.com/featured/Superfamilies
font_add_google("Montserrat", "Montserrat")
font_add_google("Roboto", "Roboto")
# Check the current search path for fonts
font_paths()
#> [1] "C:\\Windows\\Fonts"
# List available font files in the search path
font_files()
#> [1] "AcadEref.ttf"
#> [2] "AGENCYB.TTF"
#> [428] "pala.ttf"
#> [429] "palab.ttf"
#> [430] "palabi.ttf"
#> [431] "palai.ttf"
### Load font from search path into showtext
# syntax: font_add(family = "", regular = "/path/to/font/file")
font_add("Palatino", "pala.ttf")
font_families()
#> [1] "sans" "serif" "mono" "wqy-microhei"
#> [5] "Montserrat" "Roboto" "Palatino"
showtext_auto() ## automatically use showtext for new devices
# Need to open Windows graphics device as
# showtext doesn not work well with RStudio built-in graphics device
# https://github.com/yixuan/showtext/issues/7
# https://journal.r-project.org/archive/2015-1/qiu.pdf
windows()
myFont1 <- "Montserrat"
myFont2 <- "Roboto"
myFont3 <- "Palatino"
library(ggplot2)
a <- ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
ggtitle("Fuel Efficiency of 32 Cars") +
xlab("Weight (x1000 lb)") + ylab("Miles per Gallon") +
theme(text = element_text(size = 16, family = myFont1)) +
annotate("text", 4, 30, label = 'Palatino Linotype',
family = myFont3, size = 10) +
annotate("text", 1, 11, label = 'Roboto', hjust = 0,
family = myFont2, size = 10)
## On-screen device
print(a)
[/g1]
## Save to PNG device
ggsave("plot_showtext.png", plot = a, width = 6, height = 6, dpi = 96)
### Save to PDF
pdf("plot_showtext.pdf", 6, 6)
print(a)
dev.off()
showtext_auto(FALSE) ## turn off if no longer needed
Для начала, есть ли проблема с использованием Process.WaitForExit вместо его опроса?
Как бы то ни было, технически возможно, что процесс завершится с удобной точки зрения, но процесс все еще присутствует некоторое время, пока он выполняет такие вещи, как очистка дискового кеша. Файл журнала особенно велик (или какая-либо операция, которая выполняет тяжелую запись на диск)?
Есть две возможности: объект процесса продолжает хранить ссылку на процесс, поэтому он завершился, но еще не был удален. Или у вас запущен второй экземпляр процесса. Чтобы убедиться в этом, необходимо также сравнить Id процесса. Попробуйте это.
....
// Start the program
process.Start();
while (!process.HasExited)
Thread.Sleep( 500 );
Process[] p = Process.GetProcessesByName( "testprogram" );
if ( p.Length != 0 && p[0].Id == process.id && ! p[0].HasExited)
throw new Exception("Oh oh");
Согласно документации MSDN для HasExited
.
Если для процесса открыт хэндл, операционная система освобождает память процесса, операционная система освобождает память процесса, когда процесс вышел, но сохраняет административную информацию о процессе, такую как хэндл, код выхода и время выхода.
Возможно, это не связано, но стоит отметить.
Если это проблема только 1/10 времени, и процесс все равно исчезает через секунду, в зависимости от использования HasExited, попробуйте просто добавить еще одну задержку после срабатывания проверки HasExited, например
while (!process.HasExited)
DoStuff();
Thread.Sleep(500);
Cleanup();
и посмотрите, сохранится ли проблема.
Лично я всегда использовал только обработчик события Exited
вместо любого вида опроса, и упрощенную пользовательскую обертку вокруг System.Diagnostics. Process
для обработки таких вещей, как безопасность потоков, обертывание вызова CloseMainWindow()
с последующим WaitForExit(timeout)
и, наконец, Kill()
, логирование и т.д., и никогда не сталкивался с проблемой.
Может проблема в тестовой программе? Этот код красиво сбрасывается / закрывается и т. Д.? Мне кажется, если тестовая программа записывает файл на диск, файл должен быть как минимум доступен (пустым или нет)