为什么2个Try / Catch块会冻结应用程序?

时间:2016-02-03 15:49:57

标签: .net vb.net winforms try-catch

我正在编写一个简单的应用程序,它将来自2个文本框的输入作为分子和分母,然后将它们传递给Reduce()方法。

我需要将文本框字符串转换为整数,但如果用户不小心键入非数字键,我不希望它停止程序,所以我将赋值放在Try ... Catch语句中为了防止这种情况发生。

然而,当我在2个文本框中输入字母并按下按钮时,窗口就会冻结并且全部变得棘手。谁能解释一下发生了什么?

这是我的代码:

Private Sub btnReduce_Click(ByVal sender As Object, 
          ByVal e As EventArgs) Handles btnReduce.Click
    Dim n As Integer
    Dim d As Integer
    Try
        n = Val(txtNum.Text)
    Catch ex As Exception
        MsgBox("Please enter a numeric numerator", , "ERROR")
        Exit Sub
    End Try
    Try
        d = Val(txtDenom.Text)
    Catch ex As Exception
        MsgBox("Please enter a numeric denominator", , "ERROR")
        Exit Sub
    End Try
    Reduce(n, d)
    Dim reduced As String = n.ToString + "/" + d.ToString
    lblDisplay.Text = "The reduced fraction is " + reduced
End Sub

1 个答案:

答案 0 :(得分:6)

而不是Try/CatchVal使用Integer.TryParse(或其他类型)。问题是Val如果不好则不会抛出异常。它将返回任何前导数字的值:

n = Val("abc")          ' == 0.0
n = Val("1a2b3c")       ' == 1.0

它也总是返回Double,所以如下:

Dim n As Integer
n = Val(txtNum.Text) 

...是Option Strict下的无效代码 - 您正在尝试将Double分配给整数。

Dim n As Integer
Dim d As Integer

' if it can parse a value, it will be stored in n
If Integer.TryParse(txtNum.Text, n) = False Then
    MsgBox("Please enter a numeric numerator", , "ERROR")
    Exit Sub
End If

If Integer.TryParse(txtDenom.Text, d) = False Then
    MsgBox("Please enter a numeric numerator", , "ERROR")
    Exit Sub
End If

Reduce(n, d)
...

*.TryParse()的一个好处是,通过返回Boolean来避免异常。例外不适用于流控制或数据验证,这是您的代码尝试使用它们的方式。

一般情况下,最好避免使用ValMid这些遗留的VB函数来支持.NET对应函数,这些函数通常更强大,更灵活,可以更好地输入。

此外,打开Option Strict - 它会将许多运行时错误和怪异的错误转换为指向行/问题的编译器错误。例如,它可能实际上并没有停留在该方法中,但后来在某处使用错误值时。