Как запустить.fsx в ФСИ
Изучение F# с помощью FSharp.Charting. Я думал, что начну с простого "привет-мира", но у меня остается больше вопросов, чем строк кода.
#load @"..\packages\FSharp.Charting.0.90.14\FSharp.Charting.fsx"
open FSharp.Charting
let chart = Chart.Line([ for x in 0 .. 10 -> x, x*x ])
chart.ShowChart()
chart.SaveChartAs(@"C:\Temp\chart.png",ChartTypes.ChartImageFormat.Png)
Это работает в интерактивном окне в VS, но я хочу выполнить этот скрипт из строки cmd (используя fsi.exe). Я связал fsx-файлы с fsi, но когда я его выполняю, он открывает fsi, но диаграмма не создается. Что мне нужно сделать?
1 ответ
Краткий ответ: добавьте следующую строку в конце вашей программы:
System.Windows.Forms.Application.Run()
Длинный ответ:
Диаграмма действительно создается, но она немедленно исчезает, потому что ваша программа немедленно завершает работу, сразу после создания диаграммы. Этого не происходит в интерактивном окне F# в Visual Studio, потому что интерактивное окно F# не закрывается сразу после выполнения вашей программы - оно просто зависает, ожидая, что вы отправите больше кода для выполнения.
Чтобы ваша программа не закрывалась сразу, вы могли бы реализовать некоторый механизм ожидания, такой как ожидание определенного количества времени (см. System.Threading.Thread.Sleep
) или в ожидании нажатия пользователем клавиши Enter (через stdin.ReadLine()
), так далее.
Однако на самом деле это вам не поможет, потому что есть следующая проблема: диаграмма рисуется с помощью Windows Forms, которая основана на цикле сообщений - в противном случае окно не может получать сообщения и поэтому не может отображать событие самостоятельно.,
FSI имеет свой собственный встроенный цикл обработки событий, и именно так ваша программа работает под VS. Тем не менее, если вы реализуете механизм ожидания (например, stdin.ReadLine()
), этот цикл событий будет заблокирован - не сможет качать сообщения. Поэтому единственный разумный способ не допустить выхода из вашей программы, не мешая функционированию окна диаграммы, - это запустить собственный цикл обработки событий. И это именно то, что Application.Run()
делает.
Сохранение на диск без отображения:
(в ответ на комментарий)
Из того, что я понимаю, FSharp.Charting
библиотека была задумана как быстрый и грязный способ отображения диаграмм на экране, основной пример использования - изучение наборов данных в реальном времени в F# Interactive. Более конкретно, некоторые ключевые свойства Chart
объект, такой как ChartAreas
а также Series
не инициализируются при создании диаграммы, а только тогда, когда она отображается на экране (см. исходный код), и без этих свойств диаграмма остается пустой.
Если не подавать запрос на извлечение в библиотеку, я рекомендую перейти к основному System.Windows.Forms.DataVisualization.Charting.Chart
:
open System.Windows.Forms.DataVisualization.Charting
let ch = new Chart()
ch.ChartAreas.Add( new ChartArea() )
let s = new Series( ChartType = SeriesChartType.Line )
s.Points.DataBind( [for x in 1..10 -> x, x*x], "Item1", "Item2", "" )
ch.Series.Add s;
ch.SaveImage(@"C:\Temp\chart.png", System.Drawing.Imaging.ImageFormat.Png)