【发布时间】:2012-11-02 07:48:49
【问题描述】:
upd 我发现 AutoResetEvent 按预期工作。看来我在CalculateAndNotify 的某个地方有异常。所以这个问题不再是关于 AutoResetEvent 了。但是,如果您能提出如何更好地在 HFT 软件中计算索引的建议,欢迎使用 cmets。
================================================ ================================
我在我的班级的完整列表下方添加。有两种重要的方法。每次调用 InstrumentUpdated 时,Calculate 都会重新计算索引值。
class CompositeIndex : CustomIndex
{
//private Tuple<Instrument, double>[] _instrumentsWithWeight;
//private int[] _instrumentIds;
//private double[] _ammounts;
//private double[] _cachedProduct; // one thread writes here and another thread reads. so need to use "Volatile"
//private volatile bool _initialized;
//AutoResetEvent are = new AutoResetEvent(false);
//public CompositeIndex(string indexId, Tuple<Instrument, double>[] instrumentsWithWeight)
// : base(indexId, GetInstruments(instrumentsWithWeight))
//{
// _instrumentsWithWeight = instrumentsWithWeight;
// _instrumentIds = new int[_instrumentsWithWeight.Count()];
// _ammounts = new double[Commons.Constants.MAX_INSTRUMENTS_NUMBER_IN_SYSTEM];
// _cachedProduct = new double[Commons.Constants.MAX_INSTRUMENTS_NUMBER_IN_SYSTEM];
Task.Factory.StartNew(() =>
{
while(true)
{
if (_initialized)
{
break;
}
Thread.Sleep(1000);
}
while (true)
{
are.WaitOne(); // hangs here!
CalculateAndNotify();
}
}
, TaskCreationOptions.LongRunning);
}
//private static List<Instrument> GetInstruments(Tuple<Instrument, double>[] instrumentsWithWeight)
//{
// List<Instrument> result = new List<Instrument>();
// for (int i = 0; i < instrumentsWithWeight.Count(); i++)
// {
// result.Add(instrumentsWithWeight[i].Item1);
// }
// return result;
//}
//protected override void Calculate()
//{
// double result = 0;
// for (int i = 0; i < _instrumentIds.Count(); i++)
// {
// int instrumentId = _instrumentIds[i];
// // we assign 0 weself so this comparision is OK
// double cachedProduct = Volatile.Read(ref _cachedProduct[instrumentId]);
// if (cachedProduct == 0)
// {
// Value = null;
// return;
// }
// result += cachedProduct;
// }
// Value = result;
//}
//private object _initializeLock = new object();
//private bool Initialize()
//{
// lock (_initializeLock)
// {
// if (_initialized)
// {
// return true;
// }
// for (int i = 0; i < _instrumentsWithWeight.Count(); i++)
// {
// Instrument instrument = _instrumentsWithWeight[i].Item1;
// double weight = _instrumentsWithWeight[i].Item2;
// _instrumentIds[i] = instrument.Id;
// _ammounts[instrument.Id] = weight;
// }
// _initialized = true;
// return true;
// }
//}
public override void InstrumentUpdated(Instrument instrument)
{
//if (!_initialized)
//{
// if (!Initialize())
// {
// return;
// }
//}
//int instrumentId = instrument.Id;
//bool useSecurityInsteadOfOrderBook = instrument.GateId == 1;
//decimal? value;
//if (useSecurityInsteadOfOrderBook)
//{
// InstrumentInfo ii = Markets.GetInstrumentInfo(instrument);
// value = ii.MedianOrAskOrBid;
//} else
//{
// Glass glass = Markets.GetGlass(instrument);
// value = glass.MedianOrAskOrBid;
//}
//if (value == null)
//{
// Volatile.Write(ref _cachedProduct[instrumentId], 0);
//}
//else
//{
// Volatile.Write(ref _cachedProduct[instrumentId], ((double)value) * _ammounts[instrumentId]);
//}
are.Set(); // called many times!
}
}
我添加了一些跟踪并注意到:
一个线程挂在are.WaitOne()。尽管另一个线程多次调用are.Set(),但第一个线程没有被释放。
为什么?我的代码有什么问题?
【问题讨论】:
-
代码太多。尝试通过删除不相关的部分来定位问题。
-
@DmitryDovgopoly 只需看看“Calculate”和“InstrumentUpdated”方法!我将评论不重要的代码。
-
calculatenotify 是做什么的。
-
@CodeIgnoto 我评论了不重要的代码。重要的是 - 当
are.Set()被调用时,我没有在are.WaitOne()中得到通知 -
@CodeIgnoto CalculateAndNotify 调用 Calculate() 然后通知侦听器。
标签: c# multithreading events autoresetevent