【问题标题】:how to run .fsx in fsi如何在 fsi 中运行 .fsx
【发布时间】:2017-10-13 13:52:59
【问题描述】:

用 FSharp.Charting 探索 F# 我以为我会从一个简单的“hello world”开始,但它给我留下的问题比代码行多。

#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 但没有创建图表。我需要做什么?

【问题讨论】:

    标签: f# fsharpchart


    【解决方案1】:

    简答:在程序末尾添加以下行:

    System.Windows.Forms.Application.Run()
    

    长答案:

    图表确实被创建了,但它立即消失了,因为您的程序在创建图表后立即退出。这不会发生在 Visual Studio 的 F# 交互窗口中,因为 F# 交互窗口不会在执行程序后立即关闭 - 它只是挂在那里,等待您提交更多代码以执行。

    为了让你的程序不会立即退出,你可以实现一些等待机制,比如等待一段时间(见System.Threading.Thread.Sleep)或者等待用户回车(通过stdin.ReadLine()),等等

    但是,这实际上对您没有帮助,因为还有下一个问题:图表是通过 Windows 窗体绘制的,它依赖于 message loop 运行 - 否则窗口无法接收消息,因此不能t 事件绘制本身。

    FSI does have its own built-in event loop,这就是您的程序在 VS 下的工作方式。但是,如果您实施“等待”机制(例如 stdin.ReadLine()),则此事件循环将被阻止 - 将无法发送消息。因此,在不干扰图表窗口功能的情况下防止程序退出的唯一明智方法是启动您自己的事件循环。这正是Application.Run() 所做的。

    保存到磁盘而不显示:

    (回应评论)

    据我了解,FSharp.Charting 库旨在作为一种在屏幕上显示图表的快捷方式,主要用例是在 F# Interactive 中探索数据集。更具体地说,Chart 对象的一些关键属性,例如 ChartAreas 和 Series 在图表创建时不会被初始化,但只有当它显示在屏幕上时(参见 source code),如果没有这些属性,图表仍然为空。

    向库提交拉取请求不足,我建议下拉到底层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)
    

    【讨论】:

    • 我明白了,谢谢。但是如何在情节生成后杀死脚本呢?有没有更好的方法来解决这个问题?
    猜你喜欢
    • 1970-01-01
    • 2011-02-24
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 2022-01-21
    相关资源
    最近更新 更多