C# 彭博API请求超时

C# 彭博API请求超时,c#,bloomberg,eventqueue,blpapi,C#,Bloomberg,Eventqueue,Blpapi,设置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 = n

设置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);
通常我可以从队列中抓取消息,但现在我遇到的情况是,如果我在应用程序的同一次运行中发出许多请求(通常在第十次运行时),我会看到一个
超时
事件类型

if (myEvent.Type == Event.EventType.TIMEOUT)
    throw new Exception("Timed Out - need to rethink this strategy");
else
    msg = myEvent.GetMessages().First();
这些都是在同一条线上制作的,但我假设在这条线上的某个地方有一些东西我正在消费而不是释放

有人有什么线索或建议吗


关于BLP的API并没有太多的参考资料,但希望我们能开始纠正这种情况

很高兴在stackoverflow上看到另一个人享受彭博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;
    }
  }

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

我从来没有真正抽出时间来解决这个问题,但我们确实找到了解决方法

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

_marketDataSession.OpenService("//blp/mktdata"); 
_staticSession.OpenService("//blp/refdata");
这意味着一个会话在订阅模式下运行,另一个更同步-我认为正是这种二元性是我们问题的根源


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

我对文档的阅读同意您需要为“//blp/mktdata”和“//blp/refdata”服务分别进行会话。

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

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

客户端似乎也有类似的问题。我通过创建数百个会话来解决这个问题,而不是在一个会话中传递数百个请求。Bloomberg可能对这种BFI(暴力和无知)方法不太满意,因为我们正在为每一次会议发送现场请求,但它是有效的。

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

如果您请求长时间的历史日内数据(这会导致彭博API生成许多事件),请不要使用API文档中指定的模式,因为这可能会导致应用程序检索所有事件的速度非常慢。 基本上,不要对会话对象调用NextEvent()!改用专用事件队列

而不是这样做:

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不是特别确定的…

谢谢。这是一个非常类似的构造(与示例代码非常相似)——在以前通过此函数调用时,我看不到任何未使用的消息。如果我只打一次电话,没关系,但打了几次电话后,它就吐了。我认为这可能与并发订阅某些实时字段有关,但很难确定……您是否在参考数据和市场数据之间共享同一队列?这可能是个问题。我认为问题在于您现在在获得引用之前显式地打开了服务。我们使用
if(session.OpenService(BlpConstants.BLP_REF_数据))返回session.GetService(BlpConstants.BLP_REF_数据);否则返回null而您最初的问题没有首先打开服务