I don't think there is anything wrong with the code but the Log("brk Ticked") never executes
B4X:
Private Sub Class_Globals
Public brktmr As Timer 'check Broker responds before Timeout
Public brkAck As Int
Public const brkTimeout As Int = 5000 '5 second timeout
End Sub
Private Sub startBroker
...
brktmr.Initialize("brktmr", brkTimeout)
brktmr.Enabled = True
...
End Sub
Private Sub brktmr_Tick
Log("brk Ticked")
brktmr.Enabled = False
brkAck = -1 ' Broker not connected
End Sub
That is why my question was has anybody seen it before I didn't expect anybody to be able to help unless they had come across it.
I have other programmes where timers are working correctly and if I write a small test app they seem to work. So it must be something to do with this App.
Does having a timer in a Class make any difference?
You should move the declaration of the Timer from Globals to Process_Globals.
From the help: Timers should be declared in Sub Process_Globals. Otherwise you may get multiple timers running when the activity is recreated.
@Patrick Clark is using his timer in a class, so the declaration in Class_Globals should be fine. The question is, where is this class initiated? How are you testing this? For example, if you are initiating this class in an Activity and then you test it but you close the activity, the timer event sub will not be called, since all Activity processing will stop. You may or may not see something in the log output about an event not being able to be processed. Again, @DonManfred is correct: We are not getting enough information from you on how this is used, how this is tested and what logs you are getting. We would need a complete log from "About to start broker" to at least several seconds after you expected the timer to fire. Right now you are giving us pretty much nothing...
You should move the declaration of the Timer from Globals to Process_Globals.
From the help: Timers should be declared in Sub Process_Globals. Otherwise you may get multiple timers running when the activity is recreated.
@OliverA , @DonManfred Thanks both for you input. At @klaus suggestion, I have moved the declaration to Sub Process_Globals and it works fine.
With regard to where I was initialising the Class. It is in (Main) Activity_Create. I then load a layout which has a number of buttons. One of which calls the startBroker in the class with msg.startBroker, so the Activity is still active.
B4X:
Sub Globals
Private msg As MSGe
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("mqtttestclient")
msg.Initialize("192.168.1.106", 51042, "", "")
End Sub
Sub BtnStart_Click
Wait For (msg.startBroker) complete (Success As Boolean)
If Success Then
lblStatus.Text = "Running"
Else
lblStatus.Text = "Couldn't Start Service"
End If
End Sub
Anyway, Thanks All. My problem is solved although i don't understand why it wouldn't work when declared in the class.
I missed that one.
You are right, it should work also when the Timer is declared in the Class.
And as you say it depends how the class is declared and initialized.
What I am doing is setting a acknowledge flag that is set to successful by a client.connect event but if that doesn't happen before the timer ticks then the Tick code set the acknowledge flag to failed
The code I am using is this and I think the problem is a conflict with the sleep and timer. If I put Log("Still Waiting" ) after the sleep it works!
Is there a better way of doing this. I don't want to continue if the connection isn't successful.
B4X:
'in the start broker sub
'
Acknowledged = 0
brktmr.Initialize("brktmr", 2000)
brktmr.Enabled = True
Do While Acknowledged = 0
Sleep(50)
Loop
'at this point Acknowledged should be:
' 1 (from the client.connected event) or
' -1 from the brktmr_Tick event
'the Timer tick
Sub brktmr_Tick
brktmr.Enabled = False
Acknowledged = -1
End Sub