web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

Session Id :
Dynamics 365 Community / Blogs / Hardik’s Dynamics Dojo / Batch Jobs in D365 F&O usin...

Batch Jobs in D365 F&O using SysOperation Framework

HardikPatel523 Profile Picture HardikPatel523 229

Batch Jobs in D365 F&O using SysOperation Framework (Without Losing Your Sanity)

Let’s start with a simple question:
Have you ever clicked a button…
…and then stared at the screen like 👁️👄👁️
waiting for it to finish?
Congratulations.
You’ve officially needed a batch job.

Why Batch Jobs Even Exist?

Imagine this:
  • You need to process 50,000 records
  • Each record takes even 0.1 seconds
That’s 5000 seconds (~83 minutes)😳
Now ask yourself:
Should a user sit and watch this happen?
Absolutely not.

That’s the problem batch jobs solve:

  • Long-running operations
  • Heavy data processing
  • Background execution
  • Scheduled automation
Basically: “Do the work… but don’t make the user suffer.”

The Real Problem (Beyond Just “Long Running”)

Batch jobs are not just about:
  • Running in background
  • Scheduling
They’re about handling scale.
Because in real projects:
  • It’s not 1,000 records
  • It’s 1 million+ records
Now imagine processing that in a single thread…
That’s like asking one person to empty an entire warehouse 🧍‍♂️

Enter Multi-Threading (The Game Changer)

Instead of:
🧍‍♂️ One worker doing everything
You get:
👷‍♂️👷‍♀️👷 Multiple workers doing chunks of work in parallel
You can:
  • Split data into batches
  • Run tasks in parallel
  • Use batch framework threads
Why Multi-Threading Matters
  • 🚀 Faster execution
  • ⚖️ Better resource utilization
  • 🧠 Scalable design
  • 🕒 Reduced batch window time

A Quick History

Back in the good old days of AX:
Developers used RunBaseBatch
And life was like:
  • Everything in one class 😵
  • UI + logic + execution = mixed masala 🍛
  • Debugging = treasure hunt 🗺️
Then came SysOperation Framework like a well-organized engineer:
“Bro… separate concerns. Be clean.”

RunBaseBatch vs SysOperation (The Real Fight)

FeatureRunBaseBatch 😵SysOperation 😎
Code StructureMixed everythingClean separation
MaintainabilityPainfulSmooth
TestabilityHardEasy
ScalabilityLimitedHigh
Modern Standard❌ Old school✅ Current

🎯 In simple words:

RunBaseBatch = “Trick that works”
SysOperation = “Engineering that scales”


What is SysOperation Framework?

Think of it like a 3-member team where everyone knows their job:
1. Contract Class → “What inputs do we need?”
2. Service Class → “What work needs to be done?”
3. Controller Class → “When and how should it run?”
No confusion. No chaos. Just clarity.

Now let’s build something actually useful.
Example: Cleanup Old Records from SalesParmTable
Requirement: Delete records from SalesParmTable based on user input: 👉 “Delete records older than X days”
  • User enters: `NumberOfDays = 30`
  • System calculates: `Today - 30`
  • Deletes records older than that date

Contract class:

[DataContract] // Mandatory
class CleanupContract
{
    int numberOfDays;

    [DataMember] // Mandatory for UI
    public int parmNumberOfDays(int _days = numberOfDays)
    {
        numberOfDays = _days;
        return numberOfDays;
    }
}

Service class:

class CleanupService
{
    public void process(CleanupContract _contract)
    {
        TransDate cutoffDate = today() - _contract.parmNumberOfDays();

        ttsbegin;

        delete_from salesParmTable
            where salesParmTable.CreatedDateTime < cutoffDate;

        ttscommit;

        info(strFmt("Deleted records older than %1 days", _contract.parmNumberOfDays()));
    }
}

Controller class:

class CleanupController extends SysOperationServiceController
{
    public static void main(Args _args)
    {
        CleanupController controller = new CleanupController(
            classStr(CleanupService),
            methodStr(CleanupService, process)
        );

        controller.parmExecutionMode(SysOperationExecutionMode::Asynchronous);
        controller.startOperation();
    }
}
You should create an Action Menu Item for the Controller class
  • Object Type → Class
  • Object → `CleanupController`
💡 This is what users click to run the batch job.


Batch Dialog – Quick Guide

OptionWhat it MeansWhen to Use
ParametersUser input from Data ContractAlways, based on requirement
Batch ProcessingRun in background or immediatelyON for long-running jobs, OFF for quick tasks
RecurrenceSchedule job executionFor automation (cleanup, integrations)
AlertsNotifications on success/failureFor important or monitored jobs
Task DescriptionName of the batch jobUse meaningful name
Batch GroupDefines which server runs the jobLeave default if unsure
PrivateVisibility of the jobYes for personal, No for shared
Critical JobMarks job as high priorityOnly for business-critical jobs
Monitoring CategoryUsed for tracking/reportingOptional


⚠️ Important Caution

Multi-threading is powerful… but dangerous if misused:
  • ❌ Database locks
  • ❌ Deadlocks
  • ❌ Performance degradation
Rule: “Parallelize smartly, not blindly.”

Reality Check

  • Junior Dev: “It works!”
  • Senior Dev: “How long does it take?”
  • Architect: “Can it scale?”

Debugging Batch Jobs (Why Your Breakpoints Ignore You)

You set breakpoints, run the job, and wait… nothing happens. It works perfectly when you run it normally, but the moment you turn on batch processing, your breakpoints act like they’ve gone on vacation.
Here’s the catch: when you run the job normally, it executes under IIS (w3wp or iisexpress), so your debugger is attached to the right process. But when you enable batch processing, the system runs your code in the Batch service instead. So your debugger is basically listening in the wrong room.
The fix is simple:
  • For normal execution → attach to w3wp or iisexpress
  • For batch execution → attach to Batch (Batch service)
Once you attach to the Batch service, your breakpoints will finally hit.
Simple rule to remember: if it’s running in batch, debug the Batch service.
And the reality?
You: “Why is my breakpoint not hitting?”
System: “Because I’m not where you think I am.” 😄

Final Thoughts

Batch jobs solve:
  • Time
  • Performance
  • User frustration
SysOperation adds:
  • Clean design
  • Reusability
Multi-threading adds:
  • 🚀 Speed
  • ⚡ Power
  • 🧠 Scalability
Don’t just write batch jobs…
Write batch jobs that:
  • Run in background ✅
  • Scale with data ✅
  • Use multiple threads ✅
Because real systems don’t deal with thousands…
They deal with millions.

Comments