Yes, I"m starting a new thread about Xojo.Core.TImers because it’s a problem. I have a window that is used in basically a slide show fashion to show image. The user has the option of automatically stepping through images at a given interval. This stepping is controlled through a standard timer placed on the window in the IDE.
On this window, I have a canvas subclass that acts like a push button. I’ve done this so I can have “advance”, “play” and “backward” buttons that can be pushed. In the action event of the timer, I push the advance button. Now I have been getting error reports occasionally about an exception being thrown. I have never been able to really duplicate it but it happens. It’s a NOE. I’ve made it so it fails silently and has never caused any issue. But I’ve not been able to figure out why. In fact, I was using some MBS Buttons and thought maybe there was a problem in Christian’s code and so I started using my own. Same issue. So I started adding more Try/Catch blocks sending me e-mails whenever it occurs. I’ve finally been able to trace the problem.
The code below is the action event for the timer mentioned above that is placed on the window. AdvanceImage is the “button” canvas subclass instance that I put on the window in the IDE. Now, I don’t get NOEs in this event. But look towards the bottom. I make the call to Xojo.Core.Timer to fire 250 milliseconds after the button is pushed. I’ll continue after the code block:
Sub Action() Handles Action
Static TimesFired as integer = 0
TimesFired = TimesFired+1
If bar.value < 99 Then
bar.value = bar.value+1
bar.Refresh
else
bar.value = bar.value+1
bar.Refresh
Try
AdvanceImage.Value = True
Catch
SendErrorEmail("Happened at AdvanceImage.Value = True in SlideTimer")
End Try
Try
AdvanceImage.Refresh
Catch
SendErrorEmail("Happened at AdvanceImage.Refresh in SlideTimer")
End Try
Try
Bar.Value = 1
Catch
SendErrorEmail("Happened at Bar.Value = 1 in SlideTimer")
End Try
' Call code to release the advance button in 250 Milliseconds
Xojo.Core.Timer.CallLater(250,AddressOf ReleaseAdvanceImageButton)
TimesFired = 0
End If
End Sub
Now, the ReleaseAdvanceImageButton method is a method of the window where I am operating. This is the code for that method:
Public Sub ReleaseAdvanceImageButton()
Try
AdvanceImage.Value = False
Catch
SendErrorEmail("Happened at AdvanceImage.Value = False")
End Try
If AdvanceImage = Nil Then
SendErrorEmail("AdvanceImage is Nil!!! - WHY?")
End If
Try
AdvanceImage.Refresh
Catch
SendErrorEmail("Happened at Advance.Refresh")
End Try
End Sub
When the error happen - this is where it is happening. Somehow, some way an object placed in the window by the IDE is suddenly NIL. Now I was trying to think how this would happen. OK, so let’s say someone decides to close the window at just exactly the right instance (the quarter second) between when the first timer pushes the button and when the CallLater method is to release it. OK, it COULD happen. However, this happens far to regularly for something that would need to be so precise to happen. It’s just not statistically possible. But I think if the Window was closed, there would be more of a problem with the timer trying to call a method of the window. So let’s scratch that and assume that the Window is staying open.
So now, it’s impossible for a control that is sitting on a window to go NIL when NOTHING calls that control to be closed. Maybe there’s a paint call going on during the time the Xojo.Core.Timer.CallLater method fires but that shouldn’t make the canvas show as NIL.
No, rather I blame something fundamentally wrong in Xojo.Core.Timer that has not been properly addressed. At times it seems things go NIL inside whatever code structure is used to handle all this. Sometimes it works fine. But at other times it does not. And Xojo needs to address it.
Bottom line: I am NOT going to use this any longer. It has caused me more grief than I can count and like a drunk, I keep going back to the bottle thinking I won’t be harmed by the next sip.
I warn everyone else not to use it either. I bet if you stop using it, and use a traditional timer or the SingleActionTimer class that Karen wrote, you might see strange errors suddenly vanish.
Beware!