Bloomberg API请求超时

设置了ReferenceDataRequest后,我将它发送到EventQueue

Service refdata = _session.GetService("//blp/refdata"); Request request = refdata.CreateRequest("ReferenceDataRequest"); // append the appropriate symbol and field data to the request EventQueue eventQueue = new EventQueue(); Guid guid = Guid.NewGuid(); CorrelationID id = new CorrelationID(guid); _session.SendRequest(request, eventQueue, id); long _eventWaitTimeout = 60000; myEvent = eventQueue.NextEvent(_eventWaitTimeout); 

通常情况下,我可以从队列中获取消息,但我现在遇到的情况是,如果我在应用程序的同一次运行中(通常在第十个左右)发出大量请求,我会看到一个TIMEOUT EventType

 if (myEvent.Type == Event.EventType.TIMEOUT) throw new Exception("Timed Out - need to rethink this strategy"); else msg = myEvent.GetMessages().First(); 

这些都是在同一个线程上进行的,但是我假设我正在消耗而不是释放的某个地方。

有人有任何线索或建议吗?

关于SO对BLP API的引用并不多,但希望我们可以开始纠正这种情况。

我只想分享一些内容,感谢您在初始post中包含的代码。

如果您长时间请求历史日内数据(导致Bloomberg API生成许多事件),请不要使用API​​文档中指定的模式,因为它可能最终使您的应用程序很慢地检索所有事件。 基本上,不要在Session对象上调用NextEvent()! 请改用专用的EventQueue。

而不是这样做:

 var cID = new CorrelationID(1); session.SendRequest(request, cID); do { Event eventObj = session.NextEvent(); ... } 

做这个:

 var cID = new CorrelationID(1); var eventQueue = new EventQueue(); session.SendRequest(request, eventQueue, cID); do { Event eventObj = eventQueue.NextEvent(); ... } 

这可以带来一些性能提升,尽管已知API不具有特别的确定性……

我并没有真正解决这个问题,但我们确实找到了解决方法。

基于服务器API文档中的一个小的,显然是一次性的评论,我们选择创建第二个会话。 一个会话负责静态请求,另一个会话负责实时。 例如

 _marketDataSession.OpenService("//blp/mktdata"); _staticSession.OpenService("//blp/refdata"); 

这意味着一个会话在订阅模式下运行,另一个会话更加同步 – 我认为正是这种二元性是我们问题的根源。

自从做出改变以来,我们没有遇到任何问题。

我对文档的阅读同意你需要为“// blp / mktdata”和“// blp / refdata”服务单独的会话。

很高兴看到stackoverflow上的另一个人享受bloomberg API的痛苦:-)

我很惭愧地说我使用以下模式(我怀疑从示例代码中复制)。 它似乎运行得相当稳健,但可能忽略了一些重要的信息。 但我没有得到你的超时问题。 它是Java,但所有语言的工作方式基本相同。

  cid = session.sendRequest(request, null); while (true) { Event event = session.nextEvent(); MessageIterator msgIter = event.messageIterator(); while (msgIter.hasNext()) { Message msg = msgIter.next(); if (msg.correlationID() == cid) { processMessage(msg, fieldStrings, result); } } if (event.eventType() == Event.EventType.RESPONSE) { break; } } 

这可能有效,因为它会消耗每个事件的所有消息。

客户似乎有类似的问题。 我通过制作数百个会话而不是在一个会话中传递数百个请求来解决它。 布隆伯格可能不满意这种BFI(蛮力和无知)方法,因为我们发送每个会话的字段请求但它的工作原理。

听起来你一次发出的请求太多了。 BB将在任何给定时间仅处理每个连接的特定数量的请求。 请注意,打开越来越多的连接将无济于事,因为每个订阅也有限制。 如果同时进行大量耗时的请求,有些可能会超时。 此外,您应该完全处理请求(直到您收到RESPONSE消息),或取消它们。 一个突出的部分请求是浪费一个插槽。 由于分成两个会话,似乎对你有帮助,听起来你也同时提出了很多订阅请求。 您是否使用订阅作为拍摄快照的方式? 这是订阅工具,获取初始值和取消订阅。 如果是这样,你应该尝试找到不同的设计。 这不是订阅的使用方式。 未完成的订阅请求也使用请求槽。 这就是为什么最好在单个订阅列表中批量尽可能多的订阅,而不是发出许多单独的请求。 希望这有助于您使用api。

顺便说一句,我无法从您的示例代码中判断出来,但是当您阻止来自事件队列的消息时,您是否也在(在单独的事件队列中)从主事件队列中读取? 您必须处理队列中的所有消息,特别是如果您有未完成的订阅。 响应可以很快排队。 如果您不处理消息,会话可能会遇到一些队列限制,这可能是您获得超时的原因。 此外,如果您没有阅读邮件,则可能会标记为消费者较慢,并且在您开始使用待处理邮件之前不会收到更多数据。 api是异步的。 事件队列只是一种阻止特定请求的方法,而不必在阻塞正常的上下文中处理来自主队列的所有消息,否则将很难中断逻辑流以异步处理部分。