C# WPF Watchdog - чтение значений PL C, выполнение кода после изменения тега PL C - PullRequest
0 голосов
/ 21 января 2020

Я ищу хороший способ выполнить длинную (1500 мс) задачу, когда PL C Сканирование тегов установило значение INT равным 1. Я также ищу пропустить длинную задачу, если она уже выполняется. По сути, я разрабатываю сканер на 100 мс для чтения и записи значений в PL C при необходимости, а затем выполняю задачи, когда значения go высокие и низкие (но некоторые занимают больше 100 мс).

Ниже это то, что у меня сейчас есть:

Когда приложение открывается, я вызываю ReadInWatchDogPLCOutputs () каждые 100 мс, чтобы сканировать изменения тега PL C и делать это асинхронно из интерфейса WPF.

private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DispatcherTimer dt = new DispatcherTimer();
            dt.Interval = TimeSpan.FromMilliseconds(100);
            dt.Tick += DTTickerAsync;
            dt.Start();
        }

private async void DTTickerAsync(object sender, EventArgs e)
        {
            await Task.Run(() => MasterPLCComms());            
        }

private void MasterPLCComms()
        {
            ReadInWatchDogPLCOutputs();            
        }

И вот пример кода внутри ReadInWatchDogPLCOutput (), который я запускаю, который занимает 1500 мс, если выполняется.

private void ReadInWatchDogPLCOutputs()
        {
            //create a connection every time task is called to to the NDM connection
            var Connection = new TagHandler();
            Connection.CreateNDMConnection(AppGlobalVars.PLCPath, AppGlobalVars.PLCIPAddress); 

            //Once a connection is made Go Ahead and Read in PLC Controller Tag
            int Trigger = Connection.GenerateReadInPLCTag_Int8("Trigger", 1);


            if (Trigger == 1) // If Trigger is High then begin task
            {
                if (InspectionGlobalVars.InspectionRunning == false) // check to see if long running process is currently running for following 100ms ticks 
                {
                    // set variable to true to prevent a double trigger from causing any issues/crashes
                    InspectionGlobalVars.InspectionRunning = true;

                    // Set Trigger Ready to 0 Since we are processing
                    Connection.GeneratePushOutPLCTag_Int8("TriggerReady", 1, 0);

                    // Set TriggerAck to 1 Since we are processing
                    Connection.GeneratePushOutPLCTag_Int8("TriggerAck", 1, 1);

                    //////////////////////////// 
                    //1500 ms inspection code goes here
                    ////////////////////////////

                    //Communicate to the PLC by updating value to 1 saying inspection is done
                    Connection.GeneratePushOutPLCTag_Int8("ResultsValid", 1, 1);

                    //Communicate to the PLC by updating value to 1 saying system can trigger again
                    Connection.GeneratePushOutPLCTag_Int8("TriggerReady", 1, 1);

                    //Set Inspection running to false since we are done 
                    InspectionGlobalVars.InspectionRunning = false;
                }
            }
            else if (Trigger == 0)
            {
                Connection.GeneratePushOutPLCTag_Int8("TriggerAck", 1, 0); // set triggerAck to zero when the PLC trigger is 0
            }
        }

Я не уверен, что лучший способ подойти к этому. Я хотел бы, чтобы код 1500 мс выполнялся, если выполняются все условия, а затем продолжал выполняться, когда следующее 100 мс сканирование проходит и запускает ReadInWatchDogPLCOutputs (). Я довольно новичок в Threading и Asyn c с WPF, поэтому любая помощь приветствуется.

...