Example #1
0
        /// <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();
        }