void controller_CurrentTimeUpdate(object sender, EventArgs e)
        {
            TimelineBaseData timeline = controller.Timeline;

            if (timeline == null)
            {
                return;
            }

            if (InvokeRequired)
            {
                Invoke(new Action(() => { controller_CurrentTimeUpdate(sender, e); }));
                return;
            }
            else
            {
                // play pending alerts
                var pendingAlerts = timeline.PendingAlertsAt(controller.CurrentTime, AppConst.TooOldThreshold);
                foreach (var pendingAlert in pendingAlerts)
                {
                    pendingAlert.Processed = soundPlayProcess.PlayAlert(pendingAlert, this.PlaySoundByACT);
                }

                // sync dataGridView
                dataGridView.DataSource = null;
                dataGridView.DataSource = timeline.VisibleItemsAt(controller.CurrentTime - TimeLeftCell.THRESHOLD, numberOfRowsToDisplay).ToList();
            }
        }