2012-11-02 49 views
-2

upd我发现AutoResetEvent按预期工作。看来我在CalculateAndNotify的某个地方有例外。所以这个问题不再是关于AutoResetEvent的。但是如果你可以建议如何更好地计算HFT软件中的指标 - 欢迎评论。AutoResetEvent由于某种原因不起作用

============================================== ================================ 我在课程的完整列表下面添加。有两个重要的方法。 Calculate正在重新计算每次调用InstrumentUpdated时的索引值。

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(),但第一个线程并未发布。 为什么?我的代码有什么问题?

+0

太多的代码。尝试通过删除不相关的部分来本地化问题。 –

+0

@DmitryDovgopoly只要看看“计算”和“InstrumentUpdated”方法!我会评论不重要的代码。 – javapowered

+0

calculatenotify做什么。 –

回答

0
public override void InstrumentUpdated(Instrument instrument) 
{ 
    //your code 
    // are.Set - do not need 

    Task.Factory.StartNew(CalculateAndNotify, TaskCreationOptions.LongRunning); 
} 

,你应该改变CalculateAndNotify

protected void CalculateAndNotify() 
{ 
    if (Monitor.TryEnter(someObject)) 
    { 
     try 
     { 
      // your code 
     } 
     finally 
     { 
      Monitor.Exit(someObject); 
     } 
    } 
} 

,可能会做你想要什么

+0

InstrumentUpdated方法应该尽快返回以防止阻止调用方。不应该添加锁。 – javapowered

+0

InstrumentUpdated不会锁定,因为它只启动新线程。 CalculateAndNotify方法应该有锁 –

+0

每当我有任何仪器更新(每秒超过100次)时,开始一个新的线程太昂贵 – javapowered

相关问题