2017-01-01 28 views
1

私はこの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) 

答えて

2

Async.Start操作はバックグラウンドで非同期ワークフローを開始し、その後、すぐにバックグラウンド作業がキューに追加されて終了します。その直後にプログラムが終了すると、バックグラウンド作業は決して実行されません。

あなたがWindowsフォームを使用してアプリケーションを作成している場合、あなたはおそらくのようなものが必要になります。

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

Start呼び出しは仕事のスケジュールを設定し、Run呼び出しがmainFormまで、アプリケーションを実行するために、Windowsフォームに制御を渡します閉じています。

これ以外の状況では、コマンドの実行後にF#Interactiveがバックグラウンド作業を実行し続けるため、スクリプトでこのコードを使用することができます。コンソールアプリケーションでは、Console.ReadLineを実行して、いつでもEnterキーを押してアプリケーションを終了させることができます。

関連する問題