When you call a workflow remotely via opencore, the arguments has be be serialized. Not all data types in .NET support serialization. If you try and parse a datatype that do not support serialization, you will either get an error in back.
When a Workflow calls another Workflow, we do not need to sterilize it but can instead parse the data directly.
But this lead to another problem when working with DataTable, DataRow and all the other types around those. They all have reference to the original data. A DataRow also has a reference to the DataTable, so when you parse a DataRow you are still transferring ALL the data. Everytime a workflow goes Idle ( when you use Delay, when you use a activity that waits for something ) it will persist the flow’s data. This can make memory usage explode, very fast.
Workflow one
loads a datatable with 10MB data.
loops over data in the datatable
calls workflow two for first row
workflow one waits for workflow two to complete, so persist data. We now use 10+10MB data
workflow two
begins doing stuff
Waits for something, We now use 10+10+10MB data
resumes and return some data
The INSTANCE of this workflow has stopped, but we keep it around until we are sure all data has been saved to disk and in OpenCore, so we still have 10MB data hanging around
Workflow one
Resumes
gets new row in the datatable
calls workflow two for second row
workflow one waits for workflow two to complete, so persist data. We now use 10+10+10MB data
workflow two
begins doing stuff
Waits for something, We now use 10+10+10+10MB data
resumes and return some data
The INSTANCE of this workflow has stopped, but we keep it around until we are sure all data has been saved to disk and in OpenCore, so we still have 10MB data hanging around
Workflow one
Resumes
gets new row in the datatable
calls workflow two for third row
workflow one waits for workflow two to complete, so persist data. We now use 10+10+10+10MB data
What makes this even worse, is we are using dotNET. Since dotNET is a garbage collected language, all the memory that is allocated is not related until the Garbage Collector has run, So even after we release the workflow instance, the memory will stay used for a while, this is why, you sometimes see an application in dotnet use HUGE amounts of ram, but when you draw out memory allocations their might not be a lot allocated.
This is why, you should always parse the DATA not the data row, or make sure you never use an activity that can make the workflow go idle ( That can be very hard to know )