首页 > 解决方案 > 从 void QuickFix 库方法中获取值

问题描述

我在 C# 中有一个QuickFix应用程序:

    public class MyQuickFixApp : IApplication
    {
        ...
        public void ToApp(Message msg, SessionID sessionID) 
        { 
            string s = msg.GetString(Tags.ClOrdID);
            ...
        }
        public void FromApp(Message msg, SessionID sessionID) { }
    }

向其他 Fix Server 发送消息的位置ToApp和回复正在发送到的位置FromApp
我需要存储已发送消息 ( s) 的标签值以选择相应的回复。ToApp方法返回无效。我试图将值存储在公共静态文件中,但它失败了。

如下所示:

    public class MyQuickFixApp : IApplication
    {
        ...
        public static string currClOrdID = ""; 
        public void ToApp(Message msg, SessionID sessionID) 
        { 
            string s = msg.GetString(Tags.ClOrdID);
            currClOrdID = s;
            ...
        }
        public void FromApp(Message msg, SessionID sessionID) 
        { 
            if (Equals(currClOrdID)) ...
        }
    }

我正在NullreferenceExceptioncurrClOrdID。这样做的一般策略是什么?请给我一些提示。

标签: c#quickfixn

解决方案


根据QuickFix/n 教程

编写应用程序的最佳方式是使用特定的强类型 Message 和 Field 类

所以你可以Crack(...);使用FromApp

using QuickFix;

public class MyApplication : MessageCracker, IApplication
{
    public void FromApp(Message msg, SessionID sessionID)
    {
        Crack(msg, sessionID);
    }
    //...
}

关于ClOrdID,您可以从消息中提取它并直接将其传递给处理函数,这比ClOrdID在多线程消息处理中保持静态变量更安全。

例如(假设您需要处理ExecutionReport消息):

public void OnMessage(QuickFix.FIX44.ExecutionReport msgReport, SessionID sessionID)
{
    string clOrdID = msgReport.ClOrdID.getValue();
    ...
    YourProcessing(clOrdID, ...);
}

请注意,OnMessage(...)将从Crack(msg, sessionID);

如果您需要存储其他数据来处理收到的消息,我会使用字典,因为您可能有几条消息待处理,并且响应可能以不可预知的顺序到达。Send此外,将此类数据存储在调用附近(和之前)而不是存储在 中似乎是合乎逻辑的ToApp,如下所示(假设您正在发送执行订单,期待ExecutionReport回复):

private ConcurrentDictionary<string, ...> _orderData = 
    new ConcurrentDictionary<string, ...>();

public bool PlaceNewOrder(...)
    {
        string clOrdID = ...;
        QuickFix.FIX44.NewOrderSingle msgOrder = 
            new QuickFix.FIX44.NewOrderSingle(new ClOrdID(clOrdID), ...);
        ...;
        _orderData.TryAdd(clOrdID, <data required for later processing>);
        // Notice the data is stored before sending the message
        // so it will be available to process a response
        Session.SendToTarget(msgOrder, sessionID);
    }

在处理响应消息时,您可以检索为此特定存储的数据clOrdID

private void YourProcessing(clOrdID, ...)
{
    ...;
    _orderData.TryGetValue(clOrdID, out ...);
    // You may want to check return value to make sure the data was stored for this clOrdID...
    ...;
}

另请注意,在某些时候您应该清理字典,例如,当您从已处理的消息中知道它是最后一个时,并且不要期望有更多的消息 this ClOrdID


推荐阅读