cancel
Showing results for 
Search instead for 
Did you mean: 

Best practices for cleanup of COM objects / UI API / DI API SDK objects

rajesh_khater
Active Participant
0 Kudos
425

In my addon, I am handling the SBOApplication's AppEvent like this:

//AppEvent handler code:

private void SboApplication_AppEvent(SAPbouiCOM.BoAppEventTypes EventType)

{

if (EventType == SAPbouiCOM.BoAppEventTypes.aet_CompanyChanged ||

EventType == SAPbouiCOM.BoAppEventTypes.aet_ServerTerminition ||

EventType == SAPbouiCOM.BoAppEventTypes.aet_ShutDown)

{

SetStatusBarText(

"Disconnecting add-on from company",

SAPbouiCOM.BoMessageTime.bmt_Short,

SAPbouiCOM.BoStatusBarMessageType.smt_None);

oCompany.Disconnect();

System.Windows.Forms.Application.Exit();

SetStatusBarText(

"Exited add-on application",

SAPbouiCOM.BoMessageTime.bmt_Short,

SAPbouiCOM.BoStatusBarMessageType.smt_Success);

}

}

private void SetStatusBarText(string text, SAPbouiCOM.BoMessageTime messageTime,

SAPbouiCOM.BoStatusBarMessageType messageType)

{

oSboApplication.StatusBar.SetText(text, messageTime, messageType);

}

Other than this, in the event handler for ItemEvent and other event handlers, do I need to take care of any cleanup of COM objects, to avoid memory leakage? What are the best practices related to COM objects in event handling code?

Do I need to call System.GC.Collect(); in each event handler function?

Do I need to write each event handler in try-catch block and explicitly set each SDK object reference to null in the finally block?

Accepted Solutions (0)

Answers (2)

Answers (2)

ANKIT_CHAUHAN
Product and Topic Expert
Product and Topic Expert

Hi rkemids,

Refer to SAP KBA 3057399 for the same.

CC: johan.hakkesteegt

Hope it helps!

Kind regards,

ANKIT CHAUHAN

SAP Business One Support

rajesh_khater
Active Participant
0 Kudos

Hi ankit.chauhan1

The SAP Note 3057399 mentions about cleanup of DI API objects.

Can you please confirm on the best practices for UI API objects, like:

SAPbouiCOM.Items oItems;

SAPbouiCOM.Item oItem;

SAPbouiCOM.Button oButton;

SAPbouiCOM.Form oForm;

SAPbouiCOM.EditText oEditText;

and many other objects.

Even Johan said he is not entirely sure for the UI API objects.

ANKIT_CHAUHAN
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi rkemids,

As far as I checked in UI API related documents, I didn't find anything to mention "ReleaseComObject", I suppose it will only be used for DIAPI related BOs.

Kind regards,

ANKIT CHAUHAN

SAP Business One Support

Johan_Hakkesteegt
Active Contributor
0 Kudos

Hi,

It depends on the object. For example the Company object you probably do not want to touch.

Any other objects like documents or master data, you will want to clean up as soon as you are done with them. It is also best to clean them up during a loop. In pseudo code:

create document object
loop
initiate object
fill object
add object
clean object
next

Easiest is to just create a small method that you can call in the loop, or in the Finally block.

Here is what I use (VB.NET so you will need to translate to C#):

Public Sub CleanUp(ByVal Obj() As Object)
        Try
            For Each o As Object In Obj
                If Not o Is Nothing Then
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(o)
                    o = Nothing
                End If
            Next
            GC.Collect()
        Catch ex As Exception
            appLog.WriteEntry("The object " & Obj.ToString & " was not released properly." & Chr(13) & ex.Message, Diagnostics.EventLogEntryType.Warning)
        End Try
    End Sub

As you can see, I use GC.Collect, but to my knowledge this is not really necessary. It causes a little overhead, and can be skipped in case of low spec hardware.

Regards,

Johan

rajesh_khater
Active Participant
0 Kudos

Hi johan.hakkesteegt ,

>> It depends on the object.

If I am using UI API objects like :

SAPbouiCOM.Items oItems;

SAPbouiCOM.Item oItem;

SAPbouiCOM.Button oButton;

SAPbouiCOM.Form oForm;

SAPbouiCOM.EditText oEditText;

do I need to call: Marshal.ReleaseComObject() for each of these objects in the finally block?

In general, how do I determine for which objects I need to call ReleaseComObject() and for which objects, I do not need to call?

Johan_Hakkesteegt
Active Contributor
0 Kudos

For the UI API, I am not entirely sure, but considering that the objects are existing buttons, and text boxes and such, already active and unique in the client GUI, I would assume that you do not need to need to call ReleaseComObject.

To my understanding you need to do this only for objects / interfaces that you created new. Usually that means DI API objects / interfaces.

rajesh_khater
Active Participant
0 Kudos

johan.hakkesteegt Yes, the objects are already active in the client GUI, but if the user closes the form, then the object is no longer active in the GUI. So if the addon holds a reference to an EditText object as a local variable in an event handler function, I wanted to know whether I need to call ReleaseComObject. Let me also check with SAP moderators on this forum.

When the variables or references to COM objects are declared as local variables, ideally they should be automatically released or garbage collected. But then even DI API objects like Documents can also be locally declared in the event handler function.

Johan, as a general question, do you know whether we need to call ReleaseComObject if the COM objects are referenced using local variables in a function body?

ankit.chauhan1 and other moderators from SAP support team, can you please confirm on this? What does SAP support team recommend?

Johan_Hakkesteegt
Active Contributor

"...do you know whether we need to call ReleaseComObject if the COM objects are referenced using local variables in a function body?"

In general yes, because they are not actually objects but interfaces. That means that the interface will be cleaned up on the local variable side, but not necessarily on the corresponding database side.

Using ReleaseComObject is simply good practise. So you do not have to be, but it is better if you do. This is also why I recommend to create a method for this, preferably with a short name 🙂

Regards,

Johan