Recently I encountered a very strange problem.

On my development PC, in a specific form, I have a matrix with choose from list in one of the column.

This choose from list when I press the ‘TAB’ key, my SBO would intermittently hang.

Under the Task Manager I can see that the SBO application is taking 50% of my CPU but never ends until I kill the task.

So, I spent almost 2 working days to debug this 🙁 , and thought to share the problem here.

Here is the environment :

1. SBO 9.0 PL 6 64bit client + 32bit Client installed – for the testing I had only 64bit client activated

2. MSSQL 2012

3. VS2012

4. Windows 8 64bit.

Here is the specific form content :

1. An SAPbouiCOM.DataTable object

2. An ChooseFromList Object to the Bin Code. (later I found out that this does not specific to BinCode)

3. A Matrix bound to the datatable object.

4. A Column in the matrix bound the Choose From List.

5. The rest of the items are not significant to this problem, so i would just ignore this here.

Here is the scenario,

OnBeforeChooseFromList of this column, I need to query OSBQ table to limit the OBIN records shown.

(for the sake of testing and simplicity I have simplified the query to directly get 1 bin code.)

The code I used  :

        private void mtxGR_colBNCD_BeforeCFL(object Sender, SAPbouiCOM.SBOItemEventArg pVal, out bool Bubble)
        {
            Bubble = true;
            try
            {
                SAPbouiCOM.ChooseFromList oCFL = _oForm.ChooseFromLists.Item("cflBNCD");
                SAPbouiCOM.Conditions oCons = new SAPbouiCOM.Conditions();
                //GC.Collect();
                string xml = BuildBinConditionsXML(null);
                oCons.LoadFromXML(xml);
                oCFL.SetConditions(oCons);
            }
            catch (Exception Ex)
            {
                SBOAddon.oApp.MessageBox(Ex.Message);
            }
        }
        public static string BuildBinConditionsXML(string WhsCode)
        {
            SAPbobsCOM.Recordset oRS = null;
            try
            {
                string sSQL = "";
                sSQL = "SELECT 1 AbsEntry";
               
                oRS = oC.GetBusinessObject(BoObjectTypes.BoRecordset);
                oRS.DoQuery(sSQL);
                String sXML = string.Format("<?xml version=\"1.0\" encoding=\"UTF-16\"?><conditions><condition alias=\"AbsEntry\" compared_field_alias=\"\" cond_value=\"{0}\" operation=\"1\" relationship=\"0\"/></conditions>", oRS.Fields.Item("AbsEntry").Value);
                return sXML;
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            finally
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(oRS);
            }
        }

As you can see from the code, before the choose from list event, I do a query, build an xml string and feed it to oCons.LoadFromXml method.

Now, with the above codes, SBO hangs intermittently when the user trigger the CFL and close the CFL form.

On my PC it almost always happen after I open and close the CFL form for about 20 times.

It turns out that the culprit is (i believe) the UIAPI + .Net Garbage collection.

If you notice my code, I called the BuildBinConditionsXML method which contains a RecordSet Object.

If we repeatedly call this method, at a point of time, GC will execute.

And with that, it seems to clear up some memory used by the CFL/Conditions object.

Once GC execute my SBO hangs !

The solution is very simple actually (yeah… once you know it everything is simple, isn’t it ? 🙂 )

for my case, I have to move the calling of the BuildBinConditionsXML method to a safer place so as not to let GC flush my CFL/Conditions object.

here is the corrected call :

        private void mtxGR_colBNCD_BeforeCFL(object Sender, SAPbouiCOM.SBOItemEventArg pVal, out bool Bubble)
        {
            Bubble = true;
            try
            {
                string xml = BuildBinConditionsXML(null);
                SAPbouiCOM.ChooseFromList oCFL = _oForm.ChooseFromLists.Item("cflBNCD");
                SAPbouiCOM.Conditions oCons = new SAPbouiCOM.Conditions();
                //GC.Collect();
                oCons.LoadFromXML(xml);
                oCFL.SetConditions(oCons);
            }
            catch (Exception Ex)
            {
                SBOAddon.oApp.MessageBox(Ex.Message);
            }
        }

Notice that I move the method to before declaring the CFL and Conditions object.

This problem is very specific.

It happens only when the CFL is bound to a matrix column and this matrix column is bound to a column in a datatable.

But it seems to be affecting objects other than ‘BIN’ also. At least I tried the same with ‘Items’ object.

Hopefully this would help somebody out there.

Cheers.

Edy

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply