hljs.configure({cssSelector: "code"}); hljs.highlightAll();

Thursday, May 25, 2023

Multi threading batch job in D365FO

 We get lot of requirements of some process that need to run in batch but sometimes batch takes time to complete because of large volume of data. In this case we can implement the Multi Threading for a batch which reduces execution time by creating multiple batch tasks at run time.

we need to create a class which creates the tasks based on our condition. In my case pushing all the customer transactions to a custom table. 

Find below code:

class MultiThreadBatch extends RunBaseBatch
{
    #Define.CurrentVersion(1)
    public ClassDescription caption()
    {
        ClassDescription ret;
        ret = 'Multhreading batch job';
        return ret;        
    }
    protected void new()
    {
        super();
    }
    public container pack()
    {
        return [#CurrentVersion];
    }
    public void run()
    {
        BatchHeader                     batchHeader;
        MultiThreadTask                 multiThreadTask;       
	CustTrans			custTrans;
		
        While select custTrans group by AccountNum
            where custTrans.isSent == NoYes::yes
        {
            if(this.isInBatch())
            {
                if(!batchHeader)
                {
                    batchHeader = BatchHeader::construct(this.parmCurrentBatch().BatchJobId);                    
                }
                multiThreadTask = MultiThreadTask::NewAccountNum(custTrans.AccountNum);
                              
                // add tasks to the batch header
                batchHeader.addRuntimeTask(multiThreadTask, this.parmCurrentBatch().RecId);           
            }
        }
        if(batchHeader)
        {
            // save the batchheader with added tasks
            batchHeader.save();
        }
    }

    public boolean showDefaultButton()
    {
        return true;
    }

    // Source showQuerySelectButton
    public boolean showQuerySelectButton()
    {
        return true;
    }

    // Source showQueryValues
    public boolean showQueryValues()
    {
        return true;
    }
    // Source unpack
    public boolean unpack(container packedClass)
    {
        //Deserializes the packedClass parameter value to an instance of the RunBase class.
        boolean         isSuccessful;
        Version         version = RunBase::getVersion(packedClass);
        container       base;        ;
        switch (version)
        {
            case #CurrentVersion:
                {
                    [version, base] = packedClass;
                    isSuccessful = true;
                    break;
                }

            default :
                return false;
        }
        return isSuccessful;        
    }
    // Source construct
    public static MultiThreadBatch construct()
    {
        return new MultiThreadBatch();
        
    }
    // Source main
    public static void main(Args _args)
    {
        MultiThreadBatch obj;        
        obj = MultiThreadBatch::construct();
        if(obj.prompt())
        {
            obj.run();
        }
    }
}
class  MultiThreadTask extends RunBaseBatch  
 {  
   custAccount custAccount;  
   #define.CurrentVersion(1)  
   #localmacro.CurrentList  
       custAccount  
     #endmacro  
   public ClassDescription caption()    
   {  
     ClassDescription ret;  
     ret = strfmt(' Multi Thread Task for customer %1' + custAccount);  
     return ret;      
   }  
   protected void new()    
   {  
     super();  
   }  
   public container pack()    
   {  
     return [#CurrentVersion,#CurrentList];      
   }  
   public custAccount newAccountNum(CustAccount _custAccount = custAccount)    
   {  
     ;  
     CustAccount = _custAccount;  
     return custAccount;      
   }  
   public void run()    
   {  
     ;  
     this.populateCustomTable(CustAccount);  
   }  
   public boolean unpack(container packedClass)    
   {  
     int version   = runbase::getVersion(packedClass);  
     switch (version)      
     {  
       case #CurrentVersion:  
         [version,#CurrentList] = packedClass;  
         return true;  
       default :  
         return false;        
     }  
     return false;      
   }  
   private static  MultiThreadTask construct()    
   {  
     return new  MultiThreadTask();      
   }  
   public static  MultiThreadTask initialize(CustAccount _custAccount)  
   {  
      MultiThreadTask multiTaskThread;  
     ;  
     multiTaskThread =  MultiThreadTask::construct();  
     multiTaskThread.NewAccountNum(_custAccount);  
     return multiTaskThread;  
   } 

	public void populateCustomTable(CustAccount _custAccount)
	{
		//insert data here
	}   
 }  


You can Click here to implement the above code using sys operation framework.


No comments:

Post a Comment