VB.NET Using a custom timer in a lambda expression in its own "new" statement - is everything all right?

It works, and I can’t imagine how it can cause problems, but the visual studio gives me a warning, and it saddens me. I'm just wondering if something like this can cause problems:

I have my own timer, which acts like Wait for a certain number of milliseconds, and then performs a function. It looks like this:

Public Class MyTimer Inherits Timers.Timer Public Event Done() Public Sub New(ByVal interval As Double, ByVal repeat As Boolean, ByVal Work As DoneEventHandler) Me.AutoReset = Not repeat End Sub Private Sub ElapsedToDoneConvert() Handles Me.Elapsed RaiseEvent Done() End Sub End Class 

I use it as follows:

 Dim Timer as New MyTimer(1000, False, Sub() ..code.. End Sub) 

or

 Dim Timer as New MyTimer(1000, True, Sub() ..code.. End Sub) 

The first case waits for one second, and then executes ... code .., the second case executes ... code .. several times every second.

Now the question is: Imagine that I have a form with a text field called TextBox1. It is safe?

 Dim Timer As MyTimer Timer = New MyTimer(1000, True, Sub() If TextBox1.Text <> String.Empty Then MsgBox("TextBox1 is no longer empty") Timer.Stop() End If End Sub) 

(So, every second, the timer checks if TextBox1 is empty. If it is not, it displays a message box and stops checking.)

I get a warning that Timer is used before it is assigned a value, but it is used in a statement that assigns its value. The timer interval must be greater than zero. Is there anything in this that I don't understand that can cause problems?

Thanks for the help!

+4
source share
2 answers

The problem is that you are using Timer in the lambda that you pass to the MyTimer constructor. When it compiles this line:

 Timer = New MyTimer(1000, True, Sub() If TextBox1.Text <> String.Empty Then MsgBox("TextBox1 is no longer empty") Timer.Stop() End If End Sub) 

The Timer instance you pass can be used by the MyTimer constructor (the compiler does not know). If this case is also because the constructor works before the result is assigned to Timer , you pass an uninitialized value and you get a warning.

You can easily fix it:

 Dim Timer As MyTimer = Nothing Timer = New MyTimer(1000, True, Sub() If TextBox1.Text <> String.Empty Then MsgBox("TextBox1 is no longer empty") Timer.Stop() End If End Sub) 

That is, explicitly set the value to "nothing" first. I think this will work, but in fact even this raises alarming calls. I would change the API so that instead of requiring you to pass the timer instance to the callback, you simply change it so that your callback returns either true or false to whether it wants to continue or not. Thus, MyTimer itself can be responsible for stopping when the timer returns false .

+2
source

You really have to put this in a using statement, so the timer is deleted every time. Your MyTimer class should also implement IDisposable.

+1
source

All Articles