6

设置 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);

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

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

这些是在同一个线程上制作的,但我假设沿着这条线的某个地方我正在消费而不是释放。

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

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

4

7 回答 7

5

感谢您在初始帖子中包含的代码,我只是想分享一些东西。

如果您长时间请求历史盘中数据(这会导致 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 不是特别确定性...

于 2011-05-25T15:48:19.543 回答
4

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

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

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

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

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

于 2009-11-24T14:57:37.087 回答
1

一位客户似乎有类似的问题。我通过进行数百个会话而不是在一个会话中传递数百个请求来解决它。彭博社可能对这种 BFI(蛮力和无知)方法不满意,因为我们会为每个会话发送现场请求,但它确实有效。

于 2010-08-01T00:28:27.390 回答
1

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

于 2009-12-02T14:02:41.270 回答
0

很高兴看到 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;
    }
  }

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

于 2009-09-18T10:06:47.143 回答
-1

顺便说一句,我无法从您的示例代码中看出,但是当您被事件队列中的消息阻止时,您是否也在从主事件队列中读取(在单独的事件队列中)?您必须处理队列外的所有消息,尤其是当您有未完成的订阅时。响应可以非常快地排队。如果您不处理消息,会话可能会达到一些队列限制,这可能就是您遇到超时的原因。此外,如果您不阅读消息,您可能会被标记为慢速消费者,并且在您开始消费未决消息之前不会收到更多数据。api是异步的。事件队列只是一种阻塞特定请求的方法,而无需在可以阻塞的上下文中处理来自主队列的所有消息,

于 2009-12-15T14:01:19.067 回答
-1

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

于 2009-12-13T22:27:51.213 回答