将异步用于需要等待时间的功能

时间:2019-12-07 04:52:11

标签: f#

这是导致我麻烦的函数的一部分。经过一些调试,我已经将这部分与我的主要功能隔离开了:

let testfunction view =
    printfn "Entry point: %s" view
    let df =  ETS.getTimeSeries myrun.tsds (myrun.initiate2 "0019.HK" view defaultbegintime defaultendtime) "unusedlegacystring"
    printfn "I am here"
    df |> ETS.printRecords
let async1 = async{testfunction("BID")}
let async2 = async{testfunction("ASK")}
let gglist = [async1;async2] //Async<unit> list 

ETS.getTimeSeries从Internet返回一个Deedle帧,并将其保存到df。
ETS.printRecords是一个辅助函数,可以很好地打印Deedle框架。

所有参数正确。我从运行中知道:

Async.Start async1
// prints out the dataframe as expected.  Same goes for async2 as well.

如果我跑步:

gglist
|> Async.Parallel
|> Async.Ignore
|> Async.RunSynchronously

仅输出

Entry point: BID
Entry point: ASK

我怀疑这可能与以下事实有关:ETS.getTimeSeries需要3秒钟到1分钟的任何时间才能将数据拉到Deedle帧,并且我缺少某种命令来等待getTimeSeries完成。

一如既往,非常感谢您的帮助。

更新:这可能与Eikon API本身不是“线程安全”(???)(ETS.getTimeSeries)有关。有人在C#中有一个解决方案,我正在努力将其重新编写为F#。如果可能的话,我会返回一个解决方案,谢谢

https://community.developers.refinitiv.com/questions/11837/eikon-net-api-accepts-2-3-time-series-requests-and.html

对于任何感兴趣的人,这里是API的F#实现(我从网络上复制了该代码,并没有任何贡献):

let getTimeSeries (tsds:ITimeSeriesDataService) (setRequestParameters:SetDataRequestParameters) (ric:ReutersInstrumentCode) : seq<IData>  =
    let mutable records = Seq.empty<IData>   // IData is seq<KeyValuePair>
    let mutable transformer = Seq.empty<IData>
    let frame = DispatcherFrame() 
    let dataReceivedCallback (dataChunk:DataChunk) =
        //transformer <- DataChunk.Records.ToTickRecords()
        records <- Seq.append records dataChunk.Records
        frame.Continue <- dataChunk.IsLast |> not  
        () 
    (tsds.SetupDataRequest(ric)
        |> setRequestParameters)  // apply the function to the TimeSeriesDataRequestSetup object
        //.WithFields([]).From(Nullable<DateTime> DateTime.Now).WithAdjustedPrice(true).WithNumberOfPoints(10).WithView("BID")
        .OnDataReceived(Action<DataChunk> dataReceivedCallback)  
        .CreateAndSend() 
        |> ignore
    Dispatcher.PushFrame(frame)  // "Enters an execute loop"         
    records   

信用:https://gist.github.com/roguetrainer/59e4f4664528c40239f1564ef7d6dcee

Update2:这是一个非常愚蠢的(但有效吗?解决方案) 创建3个ETS.getTimeSeries实例。我们称它们为ETS.getTimeSeries1,ETS.getTimeSeries2和ETS.getTimeSeries3

使用getTimeSeries1等手动硬编码task1

[task1; task2; task3] |> Async.Parallel |> Async.Ignore |> Async.StartImmediate
//work as expected

我有一个16core / 32thread Gen1 TR CPU,所以我想我可以硬编码多达32个线程来充分利用此优势。...

0 个答案:

没有答案