Accueil → WINDEV 23 → WD22 - Thread Freeze program - Help me
WD22 - Thread Freeze program - Help me
Débuté par Giovanni Carella, 06 juil. 2018 09:50 - 8 réponses
Posté le 06 juillet 2018 - 09:50
Hi all,
i need your help.

In my application i have a this procedure:

PROCEDURE ProcessoSilente() //Procedura nata per gestire tutti i processi silenti in WiNeMo // I processi gestiti sono: //1 - Controllo Utente //2 - Invio E-Mail //3 - StatisticheEmail //4 - Statistiche CRM //5 - StatisticheVarie //6 - Statistiche WElectroCom DataOggi is Date = DateSys() OraOggi is Time = TimeSys() arrElencoTaskParalleli is array of ParallelTask parte_alfa,Causale,tipo_documento is string nConteggioEsecuzioneProcedura is numeric = 0 WHILE True nConteggioEsecuzioneProcedura++ // 1 - Controllo utente: Serve per gestire il corretto uso degli utenti in WiNeMo IF InTestMode() THEN Trace("Controllo connsessione utente " + gsUtente ) ora is numeric = TimeSys() IF gsUtente<>"" THEN HReadSeekFirst(Utenti,UT_NOME,gsUtente,hLockNo) IF HFound(Utenti) THEN Utenti.UT_CTRL=ora HModify(Utenti) ELSE DelayBeforeClosing(2000) Error("Manomissione controllo utente. Il programma verrà terminato!") EndProgram() END ELSE IF InTestMode() THEN Trace("ERRORE CONTROLLO UTENTE") END //-------------------------------------------------------------------------------------------------------------- // 2 - Invio E-Mail: Controlla tutte le e-mail che l'utente ha in queue in questo momento e le invia FOR i = 1 TO ArrayCount(arrElencoTaskParalleli) IF arrElencoTaskParalleli.Completed=True THEN ArrayDelete(arrElencoTaskParalleli,i) END END IF ArrayCount(arrElencoTaskParalleli)=0 AND DecimalPart(nConteggioEsecuzioneProcedura/3)=0 THEN DataOggi = DateSys() OraOggi = TimeSys() HReadSeekFirst(azienda,azie_key,gsAzienda) HReadSeekFirst(utentia,Uten_key,gsUtente) HReadSeekFirst(accountmail,Am_Id,utentia.uten_id_mail) IF InTestMode() THEN Trace("Controllo MAIL") END IF HExecuteQuery(QRY_SelezionaQueueMailDaInviare,hQueryDefault,DataOggi,OraOggi,gsUtente) THEN HReadFirst(QRY_SelezionaQueueMailDaInviare) WHILE NOT HOut(QRY_SelezionaQueueMailDaInviare) let t = ParallelTaskExecute(COL_Queue.InvioEmailInQueueSingolo,(QRY_SelezionaQueueMailDaInviare.QM_ID),ptoFullCopyHFSQLContext) Add(arrElencoTaskParalleli,t) HReadNext(QRY_SelezionaQueueMailDaInviare) END END END IF InTestMode() THEN Trace(""+ArrayCount(arrElencoTaskParalleli)) //-------------------------------------------------------------------------------------------------------------- //3 - StatisticheEmail IF HExecuteQuery(QRY_CountEmailInQueue,hQueryDefault,gsUtente,gsAzienda) THEN HReadFirst(QRY_CountEmailInQueue) IF HFound(QRY_CountEmailInQueue) THEN nEmMailInInvio=QRY_CountEmailInQueue.Count_1 ELSE nEmMailInInvio=0 END END IF HExecuteQuery(QRY_CountMailInErrore,hQueryDefault,gsUtente,gsAzienda) THEN HReadFirst(QRY_CountMailInErrore) IF HFound(QRY_CountMailInErrore) THEN nEmailInErrore=QRY_CountMailInErrore.Count_1 ELSE nEmailInErrore=0 END END IF HExecuteQuery(QRY_CountEmailInQueueTutti,hQueryDefault,gsAzienda) THEN HReadFirst(QRY_CountEmailInQueueTutti) IF HFound(QRY_CountEmailInQueueTutti) THEN nEmailInvioTuttiUtenti=QRY_CountEmailInQueueTutti.Count_1 ELSE nEmailInvioTuttiUtenti=0 END END IF HExecuteQuery(QRY_CountMailInErroreTutti,hQueryDefault,gsAzienda) THEN HReadFirst(QRY_CountMailInErroreTutti) IF HFound(QRY_CountMailInErroreTutti) THEN nEmailErroreTuttiUtenti=QRY_CountMailInErroreTutti.Count_1 ELSE nEmailErroreTuttiUtenti=0 END END //-------------------------------------------------------------------------------------------------------------- //4 - Statistiche CRM IF InTestMode() THEN Trace("STATISTICHE CRM") HExecuteQuery(QRY_StatisticheCRM,hQueryDefault,gsAzienda,0,Null) HReadFirst(QRY_StatisticheCRM) gxAttivitaAperteTot=QRY_StatisticheCRM.Count_1 HExecuteQuery(QRY_StatisticheCRM,hQueryDefault,gsAzienda,1,Null) HReadFirst(QRY_StatisticheCRM) gxAttivitaChiuseTot=QRY_StatisticheCRM.Count_1 HExecuteQuery(QRY_StatisticheCRM,hQueryDefault,gsAzienda,0,gsUtente) HReadFirst(QRY_StatisticheCRM) gxAttivitaAperteUtente=QRY_StatisticheCRM.Count_1 HExecuteQuery(QRY_StatisticheCRM,hQueryDefault,gsAzienda,1,gsUtente) HReadFirst(QRY_StatisticheCRM) gxAttivitaChiuseUtente=QRY_StatisticheCRM.Count_1 HExecuteQuery(QRY_CRM_Cerca_fra2_date,hQueryDefault,gsAzienda,Null,Null,gsUtente) HReadFirst(QRY_CRM_Cerca_fra2_date) WHILE NOT HOut(QRY_CRM_Cerca_fra2_date) IF QRY_CRM_Cerca_fra2_date.FlChiuso=0 THEN ArrayAdd(garrElencoAttivitaAperteUtente,QRY_CRM_Cerca_fra2_date.Descrizione+" - "+ QRY_CRM_Cerca_fra2_date.Note) END HReadNext(QRY_CRM_Cerca_fra2_date) END //-------------------------------------------------------------------------------------------------------------- //5 - StatisticheVarie IF InTestMode() THEN Trace("Calcolo ricavo/Calcolo cestino") IF NOT HExecuteQuery(QRY_Venduto_Totale_Da_A,WiNeMo_connection,hQueryWithoutCorrection,DateSys(),DateSys(),"'"+gsAzienda+"'") THEN IF InTestMode() THEN Trace("ERRORE ESECUZIONE") END HReadFirst(QRY_Venduto_Totale_Da_A) gxRicavoGiornaliero=QRY_Venduto_Totale_Da_A.Venduto-QRY_Venduto_Totale_Da_A.CostoVenduto HExecuteQuery(QRY_Conta_TRASH,hQueryDefault,gsAzienda) HReadFirst(QRY_Conta_TRASH) gxNumDocumentiCestinati=QRY_Conta_TRASH.Count_1 //-------------------------------------------------------------------------------------------------------------- //6 - Statistiche WElectroCom IF DecimalPart(nConteggioEsecuzioneProcedura/6)=0 THEN IF InTestMode() THEN Trace("Controllo Ordini WElectroComm") HReadSeekFirst(webparameter,wbp_Tipo,"CONF_ALFA") IF HFound THEN parte_alfa=webparameter.wbp_Valore END HReadSeekFirst(webparameter,wbp_Tipo,"CONF_CAUSALE") IF HFound THEN Causale=webparameter.wbp_Valore END HReadSeekFirst(webparameter,wbp_Tipo,"CONF_TIPDOC_WEB") IF HFound THEN tipo_documento=webparameter.wbp_Valore END HExecuteQuery(QRY_SelezionaOrdiniWElectroComm,hQueryDefault,tipo_documento,parte_alfa,Causale) HReadFirst(QRY_SelezionaOrdiniWElectroComm) IF HFound(QRY_SelezionaOrdiniWElectroComm) THEN gxNumOrdiniWEletrocom=QRY_SelezionaOrdiniWElectroComm.Count_1 ELSE gxNumOrdiniWEletrocom=0 END END //-------------------------------------------------------------------------------------------------------------- CriticalSectionStart() ExecuteMainThread(WIN_Menu_winemo.DoUpadateDashboard) CriticalSectionEnd() IF gbFl_Exit_Processo_silente=True THEN BREAK END ThreadPause(500) END

This procedure is performed with this thread, after a logon user:

The "ExecuteMainThread(WIN_Menu_winemo.DoUpadateDashboard)" perform this procedure:

PROCEDURE DoUpadateDashboard() DashDisplay(DASH_NoName1,IW_Cestino) DashDisplay(DASH_NoName1,IW_CostoGiornaliero_New) DashDisplay(WIN_Menu_winemo.DASH_NoName1,IW_CRM) DashDisplay(WIN_Menu_winemo.DASH_NoName1,IW_WSendMail_New) DashDisplay(DASH_NoName1,IW_WElectroComm_New)

In same case the program Freeze and i dont understand why.

I'm going crazy.
Posté le 06 juillet 2018 - 15:32
I think I found the problem.

In WinDev the "While TRUE" is not good.
Membre enregistré
292 messages
Posté le 06 juillet 2018 - 23:22

Just to let you know theres a button on the edit of this website called insert code with blue and red press that it will show some options select Wlanguage then it will appear [ code:wl ] and in the end [ / code ] between the two of those put your code it will be easier to read.

Best Regards
Posté le 17 juillet 2018 - 09:35
Hi all,
i don't find a solution.

I have rewrite all the procedure in a class.
This procedure is set like this:


The class is this:


The program, in same case, freeze.....

Please help me
Posté le 17 juillet 2018 - 13:18
Hi Giovanni,

You are saying that this code is used in a thread, and yet you are doing ERROR, TRACE and maye other UI access.

As CLEARLY stated in the threads help, ALL ACCESS TO UI IS FORBIDDEN.

So I suggest that you read the help about threads in details and replace your code accessing the UI by the appropriate thread friendly instructions.

Best regards
Posté le 17 juillet 2018 - 13:53
I also see a global variable gsUtente ?
That will be a potential problem too.
You should either avoid them (in this case it looks to me you can just pass it's value while starting the threaded procedure)
Otherwise you need to add critical sections as well.

Threading can be quite tricky at runtime, and even more when debugging
Posté le 17 juillet 2018 - 14:40
Thanks for attention.


In the class i don't use "error" and "trace".
The ErrorInfo() function is an UI acces??

Now i declared the gsUtente variable with a critical section.

gsUtente is string, critical Section
Posté le 17 juillet 2018 - 15:01

ANYTHING displayed on screen, trace function (even toward a file) is a UI function.
Accessing a UI field is a UI function.

As for your classes, I didn't take the time to download/add them in a project/analyse them. I just looked at the code that you displayed here.

Best regards
Posté le 17 juillet 2018 - 15:18
i modified the code of the first post.

I think that all UI access is in another funcion called by ExecuteMainThread().

Now i change the gsUtente and gsAzienda variable in critical section by this declaration:

gsUtente is string, critical Section
gsAzienda is string, critical Section

I hope that work fine now