public void OnExperimentalUnitLaunched(ExperimentalUnit expUnit)
        {
            MonitoredExperimentalUnitViewModel expUnitVM = new MonitoredExperimentalUnitViewModel(expUnit, m_evaluationPlot);

            ViewModelFromName[expUnit.Name] = expUnitVM;
            MonitoredExperimentalUnits.Add(expUnitVM);
        }
        public void OnMessageReceived(string experimentId, string messageId, string messageContent)
        {
            MonitoredExperimentalUnitViewModel experimentVM = ViewModelFromName[experimentId];

            if (experimentVM == null)
            {
                m_logFunction?.Invoke("Could not find the View-Model for experiment " + experimentId);
            }
            else
            {
                experimentVM.LastHeartbeat = DateTime.Now;
                LastHeartbeat = DateTime.Now;
                switch (messageId)
                {
                case JobDispatcher.ProgressMessage:
                    double progress = double.Parse(messageContent, CultureInfo.InvariantCulture);
                    experimentVM.Progress = Convert.ToInt32(progress);
                    break;

                case JobDispatcher.EvaluationMessage:
                    //<Evaluation>0.0,-1.23</Evaluation>
                    string[] values     = messageContent.Split(',');
                    string   seriesName = experimentVM.Name;
                    int      seriesId;
                    if (values.Length == 2)
                    {
                        if (!m_experimentSeriesId.Keys.Contains(experimentVM.Name))
                        {
                            seriesId = m_evaluationPlot.AddLineSeries(seriesName);
                            m_experimentSeriesId.Add(seriesName, seriesId);
                        }
                        else
                        {
                            seriesId = m_experimentSeriesId[seriesName];
                        }

                        m_evaluationPlot.AddLineSeriesValue(seriesId, double.Parse(values[0], CultureInfo.InvariantCulture)
                                                            , double.Parse(values[1], CultureInfo.InvariantCulture));
                    }
                    break;

                case JobDispatcher.GeneralMessage:
                    experimentVM.AddStatusInfoLine(messageContent);
                    break;

                case JobDispatcher.EndMessage:
                    if (messageContent == JobDispatcher.EndMessageOk || messageContent == "")
                    {
                        m_logFunction?.Invoke("Job finished sucessfully");
                        experimentVM.State = Monitoring.State.WAITING_RESULT;
                    }
                    else
                    {
                        m_logFunction?.Invoke("Remote job execution wasn't successful");
                        //Right now, my view on adding failed experiments back to the pending exp. list:
                        //Some experiments may fail because the parameters are just invalid (i.e. FAST)
                        //Much more likely than a network-related error or some other user-related problem
                        //FailedExperiments.Add(experimentVM);
                        experimentVM.State = Monitoring.State.ERROR;
                    }
                    break;
                }
            }
        }
        public void OnStateChanged(string experimentId, Monitoring.State state)
        {
            MonitoredExperimentalUnitViewModel experimentVM = ViewModelFromName[experimentId];

            experimentVM.State = state;
        }