Forum Migration Notice
We're transitioning to a more modern community platform by the end of this year. Learn about the upcoming changes and what to expect.

Is it possible to iterate through all tasks without any information of the tasks?

I am trying to create a function where I check if all tasks are running or not, but I cant find a way to iterate through all tasks.

I am thinking something like this
<div>&nbsp; &nbsp; &nbsp; &nbsp; FOR taskNo FROM 1 TO 20 DO</div><div>            IF NOT TaskIsExecuting(taskNo) RETURN FALSE;<br></div><div>&nbsp; &nbsp; &nbsp; &nbsp; ENDFOR</div>
but the TaskIsExecuting-function does not take a number as input.

I'd rather not use the ReadCfgData to analyze the systemparameters if not absolutely neccecary.
//Markus Näslund

Answers

  • lemster68
    lemster68 ✭✭✭
    TaskIsExecuting("T_Rob" + NumToStr(TaskNo,0))
    Lee Justice
  • SomeTekk
    SomeTekk
    edited March 2020
    It is suggested to try an array with the task names.

    CONST string stTaskNames {5}:= ["T_ROB1", ... T_TaskX"];
    ...

    FOR index FROM 1 to dim(stTaskNames,1) DO

    IF NOT TaskIsExecuting(stTaskNames {index}) RETURN FALSE


  • Thank for your suggestions, but unfortunately I don't know anything about the present tasks at "compile-time" so I cannot use the array-solution.
    Also, I cannot take for granted that the tasks are named in a certain way so to build the tasknames is not an option.


    //Markus Näslund
  • lemster68
    lemster68 ✭✭✭
    It sounds then like you are going to have to go with ReadCfgData.
    Lee Justice
  • Micky
    Micky ✭✭✭
    Hello,

    I agree with lemester68 to use the ReaedCfgData, but it is not possible to search directly for the names of the tasks, because you could only search for the value of a string parameter in the configuration data.

    The following code searches only for all normal tasks in the system:
    LOCAL PROC GetTaskName()
        VAR num nListIndex;
        VAR string stTaskName;
    
        !read all normal task names from sys.cfg
        WHILE nListIndex<>END_OF_LIST DO
          ReadCfgData "/SYS/CAB_TASKS/Type/NORMAL","Name",stTaskName\ListNo:=nListIndex;
          TPWrite "Task name: "+stTaskName;
        ENDWHILE
    
      ENDPROC
    If you want to search for all task types you have to add a search for the static and semi-static tasks.

  • Thanks for your suggestion. I have already considered this but I was looking for an "easier" way. Something like GetTaskName 1; would give me the name of task 1. 
    //Markus Näslund
  • Hi Markus,

    Did you ever happen across a convenient way of doing this?
    I ended up writing a module (below) to discover the tasks and store some info about them, 
    but was also looking for a more simple way to get the data

    %%%
    	VERSION:1.0
    	LANGUAGE:ENGLISH
    %%%
    
    MODULE Forge_Task(SYSMODULE)
    !--------------------------------------------------------------------------------------------------!
    !	Description:	Example Description															   !
    !																								   !
    !	| Revision | Date 		| Author | Description												   !
    !	|----------|------------|--------|-------------------------------------------------------------!
    !	| 1.0	   | 2022/03/07 | H.P.   | Document Creation										   !
    !--------------------------------------------------------------------------------------------------!
        
    	! Create an alias for the string datatype for task types, Normal, Static, SemiStatic
    	ALIAS string tasktype;
    	
    	! Create a record for storing data about all tasks in the system
        RECORD fe_taskdata
    		string Name; 		! Task name from the Controller System Config
    		tasktype Type;		! The type of task in case this is relevant for certain operations
    		tsp_status Status;	! Task active in controller status
    		bool Executing;		! Task executing in controller status
    	ENDRECORD
    	
    	! Constants representing each type of task
    	CONST tasktype TKT_Normal 		:= "NORMAL";
    	CONST tasktype TKT_Static 		:= "STATIC";
    	CONST tasktype TKT_SemiStatic 	:= "SEMISTATIC";
    	CONST tasktype TKT_None 		:= "";
    	! Store an array of the task types for easy searching
    	VAR tasktype tkt_Types{4} := [TKT_Normal, TKT_SemiStatic, TKT_Static, TKT_None]; 
    	CONST num N_NumTaskTypes := 4; ! Number of different task types
    	
    	! An array storing all task data
    	PERS fe_taskdata tsd_Tasks{20} := [["T_ROB1","NORMAL",14,TRUE],["T_ROB1_GUI","NORMAL",14,TRUE],["T_ROB1_Maintenance","NORMAL",14,FALSE],["T_ROB1_Background","SEMISTATIC",14,TRUE],["tAwSys_1","STATIC",13,TRUE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE]];
    	CONST num N_MaxTasks := 20; ! The maximum number of concurrent tasks
    	
        !**********************************************************************************************!
        PROC LoadTasksFromConfig(INOUT fe_TaskData Tasks{*})										   !
        ! Description:																				   !
        ! 	Loads all task data into the given array												   !
        !																							   !
        ! Parameters:																				   !
        ! 	INOUT fe_taskData Tasks	-	An array, empty or otherwise of task data to be filled		   !
        !																							   !
        ! Author: Harry Parker		Date: 2022/03/07		Revision: 1.0							   !
        !**********************************************************************************************!
            
            VAR num n_CfgIndex := 0;		! Index of the configuration attribute in the instance list
    		VAR string s_TaskName := ""; 	! Task name of searched task from the config file
    		VAR num n_ListIndex := 1;		! The index of the input array to store the task data in
    		VAR num n_TaskTypeIndex := 1; 	! The index of the current task type to search for
    		
    		! Loop through the array of stored tasks, while searching the config file for tasks
    		WHILE n_ListIndex <= N_MaxTasks DO
    			! If there are still task types to search for
    			IF n_TaskTypeIndex <= N_NumTaskTypes - 1 THEN
    				! Try and read the next name of a normal task from the config data
    				ReadCfgData "/SYS/CAB_TASKS/Type/" + tkt_Types{n_TaskTypeIndex}, "Name", s_TaskName, \ListNo:=n_CfgIndex;
    				! If the end of the list has been reached
    				IF n_CfgIndex = N_EndOfList THEN
    					! Have found all tasks of this type, search for the next type
    					Incr n_TaskTypeIndex;
    					! Reset the search index to search from 0 for the next type
    					n_CfgIndex := 0;
    				ENDIF
    			ENDIF
    			! Store the task name in the list
    			Tasks{n_ListIndex}.Name := s_TaskName;
    			! Store the task type in the list
    			Tasks{n_ListIndex}.Type := tkt_Types{n_TaskTypeIndex};
    			! Update the task executing boolean & status for this task
    			UpdateTaskData Tasks{n_ListIndex};
    			! Increment the list index
    			Incr n_ListIndex;
    		ENDWHILE
    	
    	!----------------------------------------------------------------------------------------------!
    	ERROR ! Error handler
    		! Check the error number for specific errors
    		TEST ERRNO
    		CASE ERR_CFG_NOTFND: ! Expected error for not finding configuration
    			! If there is no config data set the index to -1 and the returned string to empty
    			n_CfgIndex := -1;
    			s_TaskName := "";
    			! Move to the next instruction
    			TRYNEXT;
    		DEFAULT: ! For other unexpected errors
    			RAISE; ! Raise the error to the calling procedure or function
    		ENDTEST
    	ENDPROC
        
    	!**********************************************************************************************!
        PROC UpdateTaskData(INOUT fe_TaskData TaskData)												   !
        ! Description:																				   !
        ! 	Updates task data for the specific task													   !
        !																							   !
        ! Parameters:																				   !
        ! 	INOUT fe_taskData TaskData	-	Task data to have the status updated					   !
        !																							   !
        ! Author: Harry Parker		Date: 2022/03/07		Revision: 1.0							   !
        !**********************************************************************************************!
    		
    		! Update the execution status of the task
    		TaskData.Executing := TaskIsExecuting(TaskData.Name);
    		! Update the active status of the task
    		TaskData.Status := GetTSPStatus(TaskData.Name);
    		
    	!----------------------------------------------------------------------------------------------!
    	ERROR ! Error handler
    		! Check the error number for specific errors
    		TEST ERRNO
    		CASE ERR_TASKNAME: ! Expected error for not finding the given task
    			! Return empty data for the executing and status parameters if no task is found
    			TaskData.Executing := FALSE;
    			TaskData.Status := -1;
    			RETURN;
    		DEFAULT: ! For other unexpected errors
    			RAISE; ! Raise the error to the calling procedure or function
    		ENDTEST
    	ENDPROC
    ENDMODULE
  • Hi,

    I did unfortunately not find a simpler way than reading the system parameters, and in the end I didn't need the functionality. But I can see you created a really elegant solution.

    Br
    //Markus Näslund