on 2023 Aug 22 9:43 AM
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?
Request clarification before answering.
Hi rkemids,
Refer to SAP KBA 3057399 for the same.
CC: johan.hakkesteegt
Hope it helps!
Kind regards,
ANKIT CHAUHAN
SAP Business One Support
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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?
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.
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?
"...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
User | Count |
---|---|
125 | |
9 | |
8 | |
6 | |
4 | |
4 | |
3 | |
3 | |
3 | |
3 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.