/// <summary> /// /// </summary> public void Start() { while (_dataSource.HaveNextTuple()) { ITuple tuple = _dataSource.GetNextTuple(); _algorithm.ReceiveNewTupe(tuple); } //触发NoMoreTuple事件 _dataSource.GetNextTuple(); }
/// <summary> /// <para>可看做生产者-消费者问题中的生产者</para> /// 这里使用lock的办法使得若是由于算法处理慢而跟不上既定StreamRate的tuple产生速度从而出现BackPressure(这里推迟了整个流数据发送,不算是真正的BackPressure),仅仅推迟下一个Tuple的发送。 /// 还有第二种解决方案(这里没有实现),可以实现一个Buffer,在进入临界区时使用tryLock方式(<see cref="System.Threading.Monitor.TryEnter"/>), /// 若lock已被占用,则将新tuple存入buffer中,产生真正的BackPressure。 /// </summary> protected void TimerThreadFunc(object state) { ITuple newTuple = _dataAdapter.GetNextTuple(); if (newTuple != null) { if (Monitor.TryEnter(mutex)) { try { //critical section start ToDoBuffer.Enqueue(newTuple); //唤醒可能等待的消费者线程 Monitor.Pulse(mutex); } catch (Exception e) { ExceptionUtil.SendErrorEventAndLog(GetType().ToString(), "Something occured while timer thread in StreamSimulator try to acquire the mutex lock. Exception Message : " + e.Message); throw e; } finally { Monitor.Exit(mutex); } } else { //没有获得锁表面消费者正在运行,无需唤醒。 //Queue不是线程安全的,由于这里没有获得锁,所以不会发生死锁的问题 lock (ToDoBuffer) { ToDoBuffer.Enqueue(newTuple); } } } }