多线程环境下SlimOrderbook拷贝异常:运行时空调试时有有效值
问题描述
在多线程环境中出现异常行为:结构体中的值在运行时为空,但断点调试模式下却能看到正常数据。
相关函数代码如下:
public static double Convert_CurrencyValue(SlimOrderbook orderBook, double amountToConvert, bool backward = false) { OrderBookPrice price; double result; if (!backward) { price = orderBook.Bids[0]; result = amountToConvert * price.Price; } else { price = orderBook.Asks[0]; result = amountToConvert / price.Price; } if (double.IsInfinity(result) || double.IsNaN(result)) { { /* 此处为断点标记 */ } } return result; }
该函数有时(并非总是)会返回无穷大,为此添加了上述if语句和断点标记用于排查问题。
出现问题时,OrderbookPrice price变量的值如下:
double Price: 0; double ImpliedProfit: 0; double Volume: 0;
但在断点标记处,SlimOrderbook orderBook.Asks[0]的值却为:
double Price: 42.5232; double ImpliedProfit: -0.01; double Volume: 0.43;
调试视图显示上述变量值存在矛盾。
相关函数与结构
主要涉及的数据结构为class Orderbook和struct SlimOrderbook
SlimOrderbook定义:
public struct SlimOrderbook { public SlimOrderbook(OrderBookPrice[] asks, double spot, OrderBookPrice[] bids) { Asks = asks; SpotPrice = spot; Bids = bids; } public OrderBookPrice[] Asks { get; private set; } public double SpotPrice { get; private set; } public OrderBookPrice[] Bids { get; private set; } } public struct OrderBookPrice { public double Price; public double Volume; public double ImpliedProfit; }
SlimOrderbook由OrderBook生成,作为本地使用的一次性工作副本,生成逻辑如下:
public SlimOrderbook GetOrderBook(Currency baseCurrency, Currency quoteCurrency) { if (baseCurrency.Equals(CurrencyPair.BaseCurrency) && quoteCurrency.Equals(CurrencyPair.QuoteCurrency)) { return new SlimOrderbook(asks: (OrderBookPrice[])Asks.Clone(), spot: SpotPrice, bids: (OrderBookPrice[])Bids.Clone()); } else if (baseCurrency.Equals(CurrencyPair.QuoteCurrency) && quoteCurrency.Equals(CurrencyPair.BaseCurrency)) { return new SlimOrderbook(asks: (OrderBookPrice[])InvertedAsks.Clone(), spot: InvertedSpotPrice, bids: (OrderBookPrice[])InvertedBids.Clone()); } else { throw new ArgumentException($"BaseCurrency {baseCurrency} or QuoteCurrency{quoteCurrency} does not match Orderbook currencies!"); } }
已尝试的修复方案
- 将
result = amountToConvert / price.Price;修改为result = amountToConvert / orderBook.Asks[0].Price;,问题未解决。 - 修改
GetOrderBook()方法,在结构体中存储数组副本而非引用,问题未解决。
内容的提问来源于stack exchange,提问作者julian bechtold
相关产品推荐
相关产品推荐

