【问题标题】:Program exits before running logic程序在运行逻辑之前退出
【发布时间】:2017-05-16 01:19:50
【问题描述】:

我正在这个MSDN 页面上玩一些图表示例,但似乎应用程序会弹出一个图表窗口,然后在呈现实际图表之前立即退出。这是我尝试运行的标题为“在后台检索数据”的示例。

open System
open System.Threading
open System.Drawing
open System.Windows.Forms
open FSharp.Charting
open System.Windows.Forms.DataVisualization.Charting

/// Add data series of the specified chart type to a chart
let addSeries typ (chart : Chart) = 
    let series = new Series(ChartType = typ)
    chart.Series.Add(series)
    series

/// Create form with chart and add the first chart series
let createChart typ = 
    let chart = new Chart(Dock = DockStyle.Fill, Palette = ChartColorPalette.Pastel)
    let mainForm = new Form(Visible = true, Width = 700, Height = 500)
    let area = new ChartArea()
    area.AxisX.MajorGrid.LineColor <- Color.LightGray
    area.AxisY.MajorGrid.LineColor <- Color.LightGray
    mainForm.Controls.Add(chart)
    chart.ChartAreas.Add(area)
    chart, addSeries typ chart

let chart, series = createChart SeriesChartType.FastLine
let axisX = chart.ChartAreas.[0].AxisX
let axisY = chart.ChartAreas.[0].AxisY

chart.ChartAreas.[0].InnerPlotPosition <- new ElementPosition(10.0f, 2.0f, 85.0f, 90.0f)

let updateRanges (n) = 
    let values = 
        seq { 
            for p in series.Points -> p.YValues.[0]
        }
    axisX.Minimum <- float n - 500.0
    axisX.Maximum <- float n
    axisY.Minimum <- values |> Seq.min |> Math.Floor
    axisY.Maximum <- values |> Seq.max |> Math.Ceiling

let ctx = SynchronizationContext.Current

let updateChart (valueX, valueY) = 
    async { 
        do! Async.SwitchToContext(ctx)
        if chart.IsDisposed then 
            do! Async.SwitchToThreadPool()
            return false
        else 
            series.Points.AddXY(valueX, valueY) |> ignore
            while series.Points.Count > 500 do
                series.Points.RemoveAt(0)
            updateRanges (valueX)
            do! Async.SwitchToThreadPool()
            return true
    }

let randomWalk = 
    let rnd = new Random()

    let rec loop (count, value) = 
        async { 
            let count, value = count + 1, value + (rnd.NextDouble() - 0.5)
            Thread.Sleep(20)
            let! running = updateChart (float count, value)
            if running then return! loop (count, value)
        }
    loop (0, 0.0)

Async.Start(randomWalk)

【问题讨论】:

    标签: f#


    【解决方案1】:

    Async.Start 操作在后台启动异步工作流,然后在后台工作添加到队列后立即结束。如果您的程序在此之后立即完成,那么后台工作将永远无法运行。

    如果您正在使用 Windows 窗体编写应用程序,那么您可能需要以下内容:

    Async.Start(randomWalk)
    Application.Run(mainForm)
    

    Start 调用将安排工作,Run 调用将控制权传递给 Windows 窗体以运行应用程序,直到 mainForm 关闭。

    在其他情况下,您可以以不同的方式处理此问题 - 在脚本中,您的代码可以工作,因为 F# Interactive 在执行命令后会继续运行后台工作。在控制台应用程序中,您可以运行 Console.ReadLine 并让用户在任何时候按回车键来终止应用程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      相关资源
      最近更新 更多