/// <summary> /// This method is constantly beeing executed by the main thread of the framework.<br/> /// Dont call this method directly. Use the Init and FinishMainThread methods. /// </summary> //TODO: Think about implement something which does really check on value changes on tableelements or triggered effects before setting update required. private void MainThreadDoIt() { //ThreadInfoList.HeartBeat("DirectOutput"); try { while (KeepMainThreadAlive) { bool UpdateRequired = false; DateTime Start = DateTime.Now; //Consume the tableelement data delivered from the calling application while (InputQueue.Count > 0 && (DateTime.Now - Start).Milliseconds <= MaxInputDataProcessingTimeMs && KeepMainThreadAlive) { TableElementData D; D = InputQueue.Dequeue(); try { //Log.Write("Pinball.MainThreadDoIt...d.name="+D.Name+", value="+D.Value+", d="+D.Number+", d="+D); Table.UpdateTableElement(D); UpdateRequired |= true; } catch (Exception E) { Log.Exception("A unhandled exception occured while processing data for table element {0} {1} with value {2}".Build(D.TableElementType, D.Number, D.Value), E); //ThreadInfoList.RecordException(E); } } if (KeepMainThreadAlive) { try { //Executed all alarms which have been scheduled for the current time UpdateRequired |= Alarms.ExecuteAlarms(DateTime.Now.AddMilliseconds(1)); } catch (Exception E) { Log.Exception("A unhandled exception occured while executing timer events.", E); //ThreadInfoList.RecordException(E); } } //Call update on output controllers if necessary if (UpdateRequired && KeepMainThreadAlive) { try { Cabinet.Update(); } catch (Exception E) { Log.Exception("A unhandled exception occured while updating the output controllers", E); //ThreadInfoList.RecordException(E); } } if (KeepMainThreadAlive) { //ThreadInfoList.HeartBeat(); //Sleep until we get more input data and/or a timer expires. DateTime NextAlarm = Alarms.GetNextAlarmTime(); lock (MainThreadLocker) { while (InputQueue.Count == 0 && NextAlarm > DateTime.Now && !MainThreadDoWork && KeepMainThreadAlive) { int TimeOut = ((int)(NextAlarm - DateTime.Now).TotalMilliseconds).Limit(1, 50); Monitor.Wait(MainThreadLocker, TimeOut); // Lock is released while we’re waiting //ThreadInfoList.HeartBeat(); } } MainThreadDoWork = false; } } } catch (Exception E) { Log.Exception("A unexpected exception occured in the DirectOutput MainThread", E); //ThreadInfoList.RecordException(E); } //ThreadInfoList.ThreadTerminates(); }