VB.NET在自己的“新”语句中使用lambda表达式中的自定义计时器 - 可以吗?

时间:2010-10-01 00:35:48

标签: vb.net lambda timer compiler-warnings variable-assignment

这是有效的,我无法想象它会如何引起问题,但是视觉工作室给了我一个警告,这让我感到难过。我只是想知道做这样的事情是否会导致问题:

我有一个自定义计时器,其作用类似于等待几毫秒,然后执行一个函数。它看起来像这样:

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

我这样用:

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

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

第一种情况等待一秒然后执行..code ..,第二种情况每隔一秒重复执行..code ..

现在问题:想象一下,我有一个带有一个名为TextBox1的文本框的表单。这样安全吗?

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)

(因此,每隔一秒,Timer会检查TextBox1是否为空。如果不是,则会显示一个消息框并停止检查。)

我收到一个警告,说明在分配值之前使用了Timer,但它在分配值的语句中使用。计时器的间隔必须大于零。有什么关于这个,我不明白会导致问题吗?

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

问题是您在传递给Timer构造函数的lambda中使用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)

传入的Timer实例可以由MyTimer构造函数使用(编译器不知道)。如果是这种情况,并且因为构造函数在结果分配给Timer之前运行,那么您传递的是未初始化的值,并且会收到警告。

你可以很容易地解决它:

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)

即,首先明确将其设置为“无”。我认为这样可行,但实际上,即使这样也会给我带来警钟。我会修改API,这样你就不需要将定时器的实例传递给回调,而只需更改它,以便你的回调返回truefalse,以确定是否要继续或不。这样,MyTimer本身可以负责在计时器返回false时停止。

答案 1 :(得分:1)

你真的应该把它放在一个using语句中,这样每次都会处理掉计时器。您的MyTimer类也应该实现IDisposable。