2

私のコードでは、プロセスを実行し、標準エラー出力 (数値) の一部を取得して、進行状況の数値を送信するイベントを発生させます。

「.First」メソッドのこの行で例外が発生することがあります。これは、文字列に分割するものがないためです。

out = mp3gain_For_NonTag.StandardError.ReadLine.Trim.Split("%").First

問題は、Try/Catch を実行せずにその例外を回避するために必要なチェックを追加することです。速度テストで、この手順での try/catch がパフォーマンスを大幅に低下させることに気付いたからです。

必要なチェックを実行するコードを単純化したいが、例外をキャッチする必要はありません (追加したチェックは、try/catch よりも迅速に実行されます)。

コードは次のとおりです。

Private Shared Sub Run_MP3Gain_NotTag()

    mp3gain_For_NonTag.Start() ' Run process

    Dim out as string  = mp3gain_For_NonTag.StandardError.ReadToEnd

    While Not mp3gain_For_NonTag.HasExited

        If Not String.IsNullOrEmpty(out) Then
            ' This would generate numbers between 1 to 100
            out = mp3gain_For_NonTag.StandardError.ReadLine.Trim.Split("%").First
        End If

        If Integer.TryParse(out, 0) Then
            RaiseEvent MP3Gain_Progress(out)
        End If

    End While

    RaiseEvent MP3Gain_Exited()

End Sub

...追加情報として、これは私がやりたくないことのサンプルです。例外の種類をキャッチしなくても、この変更されたコード コードのように try キャッチを追加すると、パフォーマンスが大幅に低下すると言えます。

Private Shared Sub Run_MP3Gain_NotTag()

    mp3gain_For_NonTag.Start() ' Run process

    Dim out as string = mp3gain_For_NonTag.StandardError.ReadToEnd 

    While Not mp3gain_For_NonTag.HasExited

        Try
            out = mp3gain_For_NonTag.StandardError.ReadLine.Trim.Split("%").First
            RaiseEvent MP3Gain_Progress(out)
        Catch : End Try

    End While

    RaiseEvent MP3Gain_Exited()

End Sub
4

5 に答える 5

2

ここで.FirstOrDefault ()があなたの答えかもしれません。

もう一度見てみました。あなたの問題は最初の方法ではないと思います。First によってスローされる例外は症状です。問題はout、ストリームの最後まで読み取って設定し、別の行を読み取ろうとして Split を実行すると、何も返されないため、例外が発生することです。分割するだけoutで、すべてがうまくいくはずです:

Dim out as string  = mp3gain_For_NonTag.StandardError.ReadToEnd

While Not mp3gain_For_NonTag.HasExited

    If Not String.IsNullOrEmpty(out) Then
        ' This would generate numbers between 1 to 100
        out = out.Trim.Split("%").First()
    End If
于 2013-10-09T20:15:48.513 に答える
1

次のように、分割文字 ( ) のインデックスを確認し、%見つかった場合にのみ分割を実行します。

If out.IndexOf("%") > -1 Then
    ' Do split logic here
End If
于 2013-10-09T20:16:48.033 に答える
1

エラー メッセージの "%" 値をチェックし、適切な値を返す関数を使用してみてください。

out = ParseError(mp3gain_For_NonTag.StandardError.ReadLine.Trim())

Private Function ParseError(msg As String) As String
    Dim retVal As String = msg
    If msg.Contains("%") Then retVal = msg.Split("%").First
    Return retVal
End Function
于 2013-10-09T20:16:56.770 に答える
1

結果ReadLineを別の変数に貼り付けて String.IsNullOrEmpty() を実行し、それをトリムして String.IsNullOrEmpty() を実行します。それでも問題ない場合は、分割して最初に実行します。エラーが発生せず、エラーを発生させてキャッチした場合よりも高速です。

Dim x as string = mp3gain_For_NonTag.StandardError.ReadLine
if Not String.IsNullOrEmpty(x) then
 x = x.trim
 If Not String.IsNullOrEmpty(x) then
  out = x.Split("%").First
 End If
End If
于 2013-10-09T20:17:10.610 に答える
1

Try/Catch ブロック自体がパフォーマンスに悪影響を与えることはありません。パフォーマンスが低下するのは、例外が実際にスローされてキャッチされたときだけです。

そうは言っても、例外の使用を完全に回避できる場合は、必ず使用する必要があります。この場合、 の結果にSplit少なくとも 1 つの要素があるかどうかを簡単に確認できます。

Dim parts = out = mp3gain_For_NonTag.StandardError.ReadLine.Trim.Split("%")
If parts.Length > 0 Then
    out = parts.First
End If

別のオプションは、FirstOrDefaultの代わりに使用することですFirstNothing結果がない場合は戻ります。

于 2013-10-09T20:17:20.910 に答える