Italian Problema con Wait For Stream_newdata

LuigiTasca

Member
Licensed User
Longtime User
Ciao a tutti,
Ho sviluppato nella mia applicazione la comunicazione con un misuratore fiscale, apro un socket su questo e scrivo i vari comandi nel flusso. Ad ogni comando inviato devo però intercettare la risposta da questo per verificarne l'esito, cosa che ho gestito con i wait for.

Esempio di un comando
B4X:
MioStream.Write("<miocomando>")
Wait For (MioStream) MioStream_newdata(Buffer() As Byte)
Dim Text As String = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
'Text è l'esito ritornato dal misuratore

Fino a qui tutto OK. Il problema è che una volta ogni n scontrini, in maniera del tutto casuale, non si scatena il wait for. L'app arriva ad eseguire il "write" ma quando deve arrivare al wait for l'esecuzione sparisce non si sa dove. In poche parole esce dalla funzione.

Il comando arriva al misuratore e viene eseguito correttamente.

B4X:
MioStream.Write("<miocomando>")
Wait For (MioStream) MioStream_newdata(Buffer() As Byte)
'<--- Non passa mai di qui
Dim Text As String = BytesToString(Buffer, 0, Buffer.Length, "UTF8")

Pensando fosse un problema del misuratore, e che fosse questo a non scrivermi niente (non generando l'evento MioStream_newdata) sono riuscito a fare una gestione con un timer nel quale scateno "MioStream_newdata" manualmente con un callsub. Ho provato questa mia "soluzione" e funzionerebbe (nei casi in cui prevedo io "manualmente" a far si che il misuratore non mi restituisca niente).

Il problema è nei casi "reali", in cui il programma esce dalla funzione al wait for che si scatena mai.

Sapete dirmi da cosa può essere dovuto o come "aggirare" il problema?

Grazie
 

LuigiTasca

Member
Licensed User
Longtime User
Senza il codice è difficile da dirsi

Immagino, purtroppo non posso proprio postare il codice.
Comunque ho scoperto perché esce. L'applicazione va in errore al Wait For e da questo errore:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.ref.WeakReference.get()' on a null object reference

Per caso qualcuno sa da cosa è dovuto? È un errore di B4A?
 

picenainformatica

Active Member
Licensed User
Longtime User
prova con: Wait For (MioStream) newdata(Buffer() As Byte)
Non provato
 

LuigiTasca

Member
Licensed User
Longtime User
L'errore riesco a simularlo solo in release. È "gestito" dentro ad un try catch ed il log(LastException.Message) mi restituisce solo questa riga.
Scusate la domanda, ma come posso fare per ottenere il messaggio d'errore completo? :confused:
 

LuigiTasca

Member
Licensed User
Longtime User
Ecco l'errore completo

work$ResumableSub_PrintReceiptresume (java line: 39630)
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.ref.WeakReference.get()' on a null object reference
at anywheresoftware.b4a.keywords.Common.WaitFor(Common.java:1713)
at com.MyCompany.myapp.work$ResumableSub_PrintReceipt.resume(work.java:39630)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:245)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:185)
at anywheresoftware.b4a.BA$2.run(BA.java:365)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5258)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.ref.WeakReference.get()' on a null object reference
 

LucaMs

Expert
Licensed User
Longtime User
Guardando il tuo codice nel "post inglese", ti suggerirei di scrivere dei log prima di ogni wait for (tipo: logcolor("ho lanciato questo comando xxxx", Colors.Blue).

Sempre una riga prima del wait for, avvia un timer (uno diverso per ogni wait for); scaduto il tempo, quindi nell'evento _tick, chiama tu stesso, usando CallSubDelayed, la "routine" che fa sì che l'attesa termini (spero di essermi spiegato, anche se non credo :D)
 

LuigiTasca

Member
Licensed User
Longtime User
Ci ho già provato :D:D
Funzionerebbe pure (nei casi in cui lo testo io, simulando la mancata risposta dal misuratore). Il problema è che l'errore è proprio nel wait for, quindi che sia scatenato l'evento newdata del misuratore o dal mio timer di "timeout" non supera mai il WaitFor. L'evento c'è.

Domanda a chi ne sa più di me... Come funziona "sotto" un Wait For a livello tecnico? Perché mi genera un WeakReference null pointer exception?
 

sirjo66

Well-Known Member
Licensed User
Longtime User
secondo me a questo punto lascia stare il Wait For e fai tu la gestione come si faceva una volta "event driver"
su alcune mie app che usano le chiamate HTTP ho preferito gestire il tutto "alla vecchia maniera" anzichè usare il Wait For

Fai una variabile globale (ad esempio la chiami Fase) dove ci scrivi dentro quello che stai facendo e quando chiama NewData con un Select dirotti il codice al punto giusto
 
Top