2013-10-29 4 views
1

응답하지 : 나는 그것을 실행할 때차트 (Fsharp.Charting)이 코드를 갖는

let errorChanged = new Event<(int * float)>() 

let learn error data w w_ iter = 
    let rec learning error data w w_ i icount = 
     //recursive(loop) fire event 
     errorChanged.Trigger(i, e) //trigger event for chart update 
     if (/**/) then 
      learning /*params*/ 
     else 
      /*do else*/ 

    let plot = LiveChart.PointIncremental(errorChanged.Publish |> Event.every 5) 
    plot.ShowChart() 
    learning error data w w_ 0 iter 

, 내가 (그리고 업데이트되지 않음) 응답하지 않습니다 포인트 차트 창을 참조하십시오. code samples에 따르면 이것은 잘 작동하지만 ... 어떻게 해결할 수 있습니까?

UPD :

내가 할 경우 :

let rec learning error data w w_ i icount = async { 
      let e = Seq.fold (fun s x -> 
             s + errorPart w w_ x x) 0.0 data 
      errorChanged.Trigger(i, e) 
      if (e > error && i <= iter) then 
       printfn "[iter] = %d of %d. [e] = %f" i icount e 
       let (w, w_) = Seq.fold (fun (w, w_) x -> 
               learnPart w w_ x x) (w, w_) data 
       return! learning error data (normalize w) (normalize w_) (i + 1) icount 
      else 
       let resultData = Seq.map (fun x -> calculatePart w w_ x) data 
       let y = resultData 
         |> Seq.map (fun (y, _) -> y) 
         |> Seq.concat 
       let x_ = resultData 
         |> Seq.map (fun (_, x_) -> x_) 
         |> Seq.concat 
       return (w, w_, e, y, x_) } 

     let plot = LiveChart.PointIncremental(errorChanged.Publish |> Event.every 5) 
     plot.ShowChart() 
     async { return! learning error data w w_ 0 iter} 
     |> Async.RunSynchronously 

나는 예외를 얻을 : 유효 크로스 스레드 작업 없습니다. Dispatcher과 같은 것이 필요합니다.

답변

3

코드 스 니펫의 문제점은 차트를 만들지 만 현재 스레드에서 learning 함수를 실행하므로 주 스레드를 차단하므로 차트를 업데이트 할 수 없습니다.

learning 함수를 async { .. } 블록에 랩핑하고 Async.Start을 사용하여 실행할 수 있습니다. 그런 다음 백그라운드에서 실행되며 차트가 업데이트 될 수 있습니다.

당신은 전체 코드를 게시하지 않았다, 그래서 테스트 할 수 없습니다, 그러나 나는 다음과 같은 일을해야 생각 :

let rec learning error data w w_ i icount = async { // Async block here! 
    (* omitted *) 
    errorChanged.Trigger(i, e) //trigger event for chart update 
    if (e > error && i <= iter) then 
     (* omitted *) 
     // Here, we now need to run the recursive call using 'return!' of async 
     return! learning error data (normalize w) (normalize w_) (i + 1) icount 
    else 
     (* omitted *) 
     return (w, w_, e, y, x_) } 

let plot = LiveChart.PointIncremental(errorChanged.Publish |> Event.every 5) 
plot.ShowChart() 

// Create workflow that will run 'learning' and then print the result 
// (this needs to return unit, so that we can use 'Async.Start') 
async { let! res = learning error data w w_ 0 iter 
     printfn "Finished: %A" res } 
|> Async.Start 
+0

에 적용하지만,이 코드는 unit''반환합니다. ** UPD **를 참조하십시오. –

0

은 아마 WinForms event loop의 부족입니다.

는, 먼저 달려 있는지 확인하기 위해이 간단한 코드를 시도 플롯 내가 learn` 기능`에서 결과를 반환해야

use form = new Form(Width=400, Height=300, Visible=true, Text="Hello charting") 
Chart.Line([for x in 0 ..10 -> x, x+x]).ShowChart() 
System.Windows.Forms.Application.Run(form)