Hi.
I have an application in VLF-WIN. In this I have a command handler RP which call a serverfunction to get a list with 2300 entries.
The first time this is run it takes around 350ms and the list is shown immediately. If i click on some other menu item and go back to the command handler it is slow. I have put some timestamps in and the call to the server and add to the list is nearly the same - 350 ms, but it is slow to show the list - up to 5 seconds.
Is that something I have to live with or is there a workaround?
/Klaus
VLF-WIN V14 SP2 and performance
Re: VLF-WIN V14 SP2 and performance
Klaus,
Do you request the data straight from the COM Handler or do you have an object that handles getting the data? For example, my com handlers will open an object dedicated for selecting the needed data (#PRIM_OBJT) and request the data from the server and then load that data into a list that the com handler will process. That COM Handler will listen when the list is ready and then process that list and close the object. By Opening the reference to the data object and then closing when complete, removes all the overhead from the COM HANDLER.
For example (this is using a Filter but same principle):
COM HANDLER - Requesting Data ( #FNCR_F01)
OBJECT DATA HANDLER ( #FNCR_DM)
COM HANDLER - Receiving Data List (#FNCR_F01)
You may already be doing this but here you go anyway. Hope this helps!
Chad
Sherrill Furniture
Do you request the data straight from the COM Handler or do you have an object that handles getting the data? For example, my com handlers will open an object dedicated for selecting the needed data (#PRIM_OBJT) and request the data from the server and then load that data into a list that the com handler will process. That COM Handler will listen when the list is ready and then process that list and close the object. By Opening the reference to the data object and then closing when complete, removes all the overhead from the COM HANDLER.
For example (this is using a Filter but same principle):
COM HANDLER - Requesting Data ( #FNCR_F01)
Code: Select all
If_Ref Com(#FNCR_DM) Is(*NULL)
Set_Ref Com(#FNCR_DM) To(*CREATE_AS #FNCR_DM)
Endif
#FNCR_DM.uGetAll
Code: Select all
Define_Evt Name(ListPrepared)
Define_Map For(*INPUT) Class(#PRIM_ACOL<#FNCR_DO>) Name(#moDropDownList) Pass(*BY_REFERENCE)
Mthroutine Name(uGetAll)
Execute Subroutine(CALLSERVER) With_Parms('GETALL')
Signal Event(ListPrepared) Modropdownlist(#gMRSchedule)
Endroutine
Subroutine Name(CALLSERVER) Parms((#STD_TEXT *RECEIVED))
Clr_List Named(#gMRSchedule)
Clr_List Named(#EXCHANGE)
Add_Entry To_List(#EXCHANGE)
#W_PGM := 'FNCRSV1'
Use Builtin(CALL_SERVER_FUNCTION) With_Args(*SSERVER_SSN #W_PGM Y Y #EXCHANGE) To_Get(#FW_RETCD)
Selectlist Named(#EXCHANGE)
Add_Entry To_List(#gMRSchedule)
Endselect
Endroutine
Code: Select all
Evtroutine Handling(#FNCR_DM.ListPrepared) Modropdownlist(#mDataList)
#avListManager.ClearList
#avListManager.BeginListUpdate
Selectlist Named(#mDataList)
#avListManager.AddtoList Nkey1(#FNCRID) Visualid1(#FNCRSTYL) Visualid2(#FNCRFIN) Ncolumn1(#FNCRSHER) Ncolumn2(#FNCRSEQ) Ncolumn3(#FNCRQTY) Dcolumn1(#FNCRCTDT.AsDisplayString( ISO ))
Endselect
#avListManager.EndListUpdate
* Make this a hidden filter
#Com_Owner.avHiddenFilter := True
Set_Ref Com(#FNCR_DM) To(*NULL)
Endroutine
Chad
Sherrill Furniture
Re: VLF-WIN V14 SP2 and performance
Hi.
Thanks. I will give it a try.
How is your <#FNCR_DO> and #gMRSchedule defined?
/Klaus
Thanks. I will give it a try.
How is your <#FNCR_DO> and #gMRSchedule defined?
/Klaus
Re: VLF-WIN V14 SP2 and performance
FNCR_DO (RP)
FNCR_DM with FNCR_DO Defined
Code: Select all
Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_OBJT *LISTFIELDS #L_FNCR)
Def_List Name(#L_FNCR) Fields(#FNCRID #FNCRDVID #FNCRSTYL #FNCRFIN #FNCRSHER #FNCRSEQ #FNCRQTY #FNCRCTDT #FNCRSTCD #STSTID #MRRFCFID #MRCFTOIVV #MRCFKDINV #STSTDVNMJ #STSTMFCD #FNFSFLID #FNFSFLNMJ #FNFSFNID #VNISID #VNISVNID #VNISTPAMV #VNISOUCD #VNISPUCD #VNISRUCD) Type(*WORKING) Entrys(*MAX)
End_Com
Code: Select all
Define_Com Class(#PRIM_ACOL<#FNCR_DO>) Name(#gMRSchedule)
Re: VLF-WIN V14 SP2 and performance
Are you clearing (emptying) the working list each time on the client before passing it to the server to fill ?
Re: VLF-WIN V14 SP2 and performance
Yes & No <grin>
If you look back at the code for "FNCR_DM" in my previous reply, the Method Routine executes a subroutine that will clear both the exchange list and the array List "#PRIM_ACOL<#FNCR_DO>".
I always keep the array list and the exchange list basically the same.
The EXCHANGE list gets passed to the Function > on the return the EXCHANGE list will populate the Array List > the Array List is then signaled back to the COM_HANDLER.
However, I do add 1 record to the EXCHANGE List after the clear. That add will populate "STD_TEXT" and/or any keys needed to process the select statements in the Server Function. The Server function will get that first entry and based on the STD_TEXT field it will call the needed subroutine.
In my previous example, I gave you a basic call that didn't pass any keys but the majority of my COM_HANDLERs will pass a key(s) to filter the needed the data. I use this approach in my COM_HANDLERs & FIlters.
I keep all my selects, adds, deletes, updates in what I call my Data Model or "_DM" for each of my master files. No COM_HANDLERS or filters does any select, add, delete or update. All they Do is create a reference to the "_DM" object when they need something > request what is needed > process the return data > destroy the "_DM" object. That eliminates the overhead.
Here's my server function:
I hope this wasn't overkill to your question. I Hope this helps.
Chad
If you look back at the code for "FNCR_DM" in my previous reply, the Method Routine executes a subroutine that will clear both the exchange list and the array List "#PRIM_ACOL<#FNCR_DO>".
I always keep the array list and the exchange list basically the same.
The EXCHANGE list gets passed to the Function > on the return the EXCHANGE list will populate the Array List > the Array List is then signaled back to the COM_HANDLER.
However, I do add 1 record to the EXCHANGE List after the clear. That add will populate "STD_TEXT" and/or any keys needed to process the select statements in the Server Function. The Server function will get that first entry and based on the STD_TEXT field it will call the needed subroutine.
In my previous example, I gave you a basic call that didn't pass any keys but the majority of my COM_HANDLERs will pass a key(s) to filter the needed the data. I use this approach in my COM_HANDLERs & FIlters.
I keep all my selects, adds, deletes, updates in what I call my Data Model or "_DM" for each of my master files. No COM_HANDLERS or filters does any select, add, delete or update. All they Do is create a reference to the "_DM" object when they need something > request what is needed > process the return data > destroy the "_DM" object. That eliminates the overhead.
Here's my server function:
Code: Select all
Function Options(*DIRECT) Rcv_List(#EXCHANGE)
Define_Com Class(#DVUS_DM) Name(#DVUS_DM)
Define Field(#W_SEARCH) Reffld(#FNFNNMUC)
Define Field(#W_TYPE) Reffld(#FNFNTPCD)
Define Field(#W_QTY) Reffld(#FNCRQTY)
Def_List Name(#EXCHANGE) Fields(#FNCRID #FNCRDVID #FNCRSTYL #FNCRFIN #FNCRSHER #FNCRSEQ #FNCRQTY #FNCRCTDT #FNCRSTCD #STSTID #MRRFCFID #MRCFTOIVV #MRCFKDINV #STSTDVNMJ #STSTMFCD #FNFSFLID #FNFSFLNMJ #FNFSFNID #VNISID #VNISVNID #VNISTPAMV #VNISOUCD #VNISPUCD #VNISRUCD #STD_TEXT #W_TYPE #W_SEARCH) Type(*WORKING) Entrys(*MAX)
Get_Entry Number(1) From_List(#EXCHANGE)
Case Of_Field(#STD_TEXT)
When Value_Is(= 'GETALL')
Execute Subroutine(GETALL)
When Value_Is(= 'DETAIL')
Execute Subroutine(Detail)
Endcase
Return
Subroutine Name(GETALL)
Clr_List Named(#EXCHANGE)
* Build Work File
Execute Subroutine(BuildWorkFile)
Select Fields(#EXCHANGE) From_File(FNCRWV02) With_Key(*USER) Nbr_Keys(*COMPUTE) Io_Error(*NEXT) Val_Error(*NEXT)
* Get STyle ID - This is crucial
Execute Subroutine(GetFrameID) With_Parms(#FNCRDVID #STSTID #STSTDVID #STSTDVNMJ #STSTMFCD)
If Cond(#STSTDVNMJ = ' ')
#STSTDVNMJ := '** CREATE FRAME **'
Endif
* Get KD & Physical Inventory
Execute Subroutine(GetInventory) With_Parms(#STSTID #MRCFTOIVV #MRCFKDINV)
* Get Finish Location
Execute Subroutine(CheckFinish) With_Parms(#FNCRDVID #FNCRFIN #STSTID #FNFSFLID #FNFSFLNMJ #FNFSFNID)
Add_Entry To_List(#EXCHANGE)
Endselect
Endroutine
Chad