【发布时间】:2012-12-02 06:31:16
【问题描述】:
我遇到了一些阻塞问题。我正在尝试从推到拉。即我想在这里访问我的数据,在这种情况下,它是通过我的 Observable 处理后的数组。
type HistoryBar =
{Open: decimal; High: decimal; Low: decimal; Close: decimal; Time: DateTime; Volume: int; RequestId: int; Index: int; Total: int}
let transformBar =
client.HistoricalData
|> Observable.map(fun args ->
{
Open = args.Open
High = args.High
Low = args.Low
Close = args.Close
Time = args.Date
Volume = args.Volume
RequestId = args.RequestId
Index = args.RecordNumber
Total = args.RecordTotal
}
)
let groupByRequest (obs:IObservable<HistoryBar>) =
let bars = obs.GroupByUntil((fun x -> x.RequestId), (fun x -> x.Where(fun y -> y.Index = y.Total - 1)))
bars.SelectMany(fun (x:IGroupedObservable<int, HistoryBar>) -> x.ToArray())
let obs = transformBar |> groupByRequest
client.RequestHistoricalData(1, sym, DateTime.Now, TimeSpan.FromDays(10.0), BarSize.OneDay, HistoricalDataType.Midpoint, 0)
如果我订阅 obs,那么只要我打电话给client.RequestHistoricalData 一切都会正常。我想做的是将 obs 转换为基础类型,在本例中为HistoryBar []。我试过使用wait、ToEnumberable,但没有成功。提取我最后创建的数据的正确方法是什么?
编辑,添加人为的 C# 示例代码以显示库的正常工作方式。我在这里真正想了解的是如何从可观察到标准列表或数组。我不确定是否需要一个可变结构才能做到这一点。如果我不得不猜测,我会说不。
static void Main(string[] args)
{
...
client.HistoricalData += client_HistoricalData;
client.RequestHistoricalData(1, sym, DateTime.Today, TimeSpan.FromDays(10), BarSize.OneDay, HistoricalDataType.Midpoint, 0);
....
}
static void client_HistoricalData(object sender, HistoricalDataEventArgs e)
{
Console.WriteLine("Open: {0}, High: {1}, Low: {2}, Close: {3}, Date: {4}, RecordId: {5}, RecordIndex: {6}", e.Open, e.High, e.Low, e.Close, e.Date, e.RequestId, e.RecordNumber);
}
【问题讨论】:
-
client.RequestHistoricalData是做什么的?请说明。在SelectMany内部调用ToArray会导致阻塞对整个序列的急切评估。 -
添加了更多细节。
client.RequestHistoricalData将进行调用以执行数据获取,这将调用与client.HistoricalData关联的事件处理程序 -
C# 中的人为代码仍然是人为的。
-
不知道为什么
ToEnumerable在这里不起作用?您将必须阻止,因为IEnumerator<T>无法产生任何东西,直到观察到某些东西向您屈服。
标签: f# system.reactive