Exceptions im BackgroundWorker an Hauptthread weiterleiten führt zu TargetInvocationException?

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von FredM.

    Exceptions im BackgroundWorker an Hauptthread weiterleiten führt zu TargetInvocationException?

    Hallo,

    ich möchte in meinem Programm eine Exception welche in einem anderen Thread geschmissen wird, an den Hauptthread weiterleiten um ihn im Unhandled Exception Event anzuzeigen.
    Leider funktioniert das nicht ganz und ich bekomme eine TargetInvokationException. Eine nicht behandelte Ausnahme des Typs "System.Reflection.TargetInvocationException" ist in mscorlib.dll aufgetreten.
    Weiß jemand ein Workaround? Womit hängt das zusammen?

    Obwohl ja bei Button1 und 2 eigentlich das gleiche passieren sollte ist das Ergebnis doch ganz anders.

    Button1: Die MessageBox zeigt MyInnerException an.
    Button2: Die MessageBox zeigt Testexception und MyInnerException an.

    Hier ein Beispiel: :?:

    VB.NET-Quellcode

    1. Option Explicit On
    2. Option Strict On
    3. Public Class Form1
    4. Private WithEvents backwk As New System.ComponentModel.BackgroundWorker
    5. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. backwk.RunWorkerAsync()
    7. End Sub
    8. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    9. ThrowExceptionWithInner()
    10. End Sub
    11. Private Sub ThrowExceptionWithInner()
    12. Try
    13. Throw New Exception("MyInnerException")
    14. Catch ex As Exception
    15. Throw New Exception("Testexception", ex)
    16. End Try
    17. End Sub
    18. Private Sub backwk_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles backwk.DoWork
    19. ThrowExceptionWithInner()
    20. End Sub
    21. Private Sub backwk_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles backwk.RunWorkerCompleted
    22. If Not IsNothing(e.Error) Then
    23. Throw e.Error
    24. End If
    25. End Sub
    26. End Class


    VB.NET-Quellcode

    1. Partial Friend Class MyApplication
    2. Private Sub MyApplication_UnhandledException(sender As Object, e As ApplicationServices.UnhandledExceptionEventArgs) Handles Me.UnhandledException
    3. Dim ExcMsg As String = ""
    4. If Not IsNothing(e.Exception) Then
    5. ExcMsg += e.Exception.Message
    6. If Not IsNothing(e.Exception.InnerException) Then
    7. ExcMsg += vbNewLine
    8. ExcMsg += e.Exception.InnerException.Message
    9. End If
    10. End If
    11. MsgBox(ExcMsg)
    12. End Sub
    13. End Class
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „FredM“ ()

    Ok ich hab eine Antwort gefunden.

    pcreview.co.uk/forums/innerexc…dledexcepti-t2781914.html


    Yes, InvokeMarshaledCallbacks() method catches the exception we throw and
    then calls "exception1.GetBaseException" method to get the inner-most
    exception object and pass it to the Application.OnThreadException() method.
    We finally find the root cause now!

    Then I want to understand why Winform InvokeMarshaledCallbacks() method
    will translate the exception into inner-most exception(Foo) for
    Application.OnThreadException() method. I performed some search in our
    internal database with one existing record regarding our problem.

    Based on the winform comfirmation in the record, our analysis is correct of
    the root cause and this behavior is intended. The reason was to prevent the
    user from seeing too much of the Windows.Forms internal mechanisms. This is
    because the winform's default error dialog also leverages
    Application.ThreadException to show the exception details. .Net Winform
    team trims the other exceptions information so that the default error
    dialog will not display all the details to the end user.

    Also, some MSFTs have sugguested to change this behavior. However, .Net
    Winform team thinks that changing the exception to throw is a breaking
    change and for this reason WinForms will keep sending the innermost
    exception to the Application.ThreadException handler.

    Hope this helps.

    Best regards,
    Jeffrey Tan
    Microsoft Online Community Support


    Dann hab ich wohl nichts falsch gemacht... Ist ja doof. Dann gibts wohl keine andere möglichkeit wie die ganze Exception mit StackTrace in ein String zu schreiben...
    Ich brauch das nämlich, um ein gescheites ErrorLog zu schreiben. Naja
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

    Ähm jetzt hab ich was ganz seltsames festgestellt...

    Eigentlich braucht man ja dafür ein Delegaten, wenn ich den Code debugge kommt auch schön die Fehlermeldung "Ungültiger threadübergreifender Vorgang"...
    Starte ich aber die kompilierte EXE gibts keine Exception und es funktioniert...

    War das schon immer so? Ich bin gerade total verwirrt...


    VB.NET-Quellcode

    1. Option Explicit On
    2. Option Strict On
    3. Public Class Form1
    4. Private WithEvents backwk As New System.ComponentModel.BackgroundWorker
    5. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. backwk.RunWorkerAsync()
    7. End Sub
    8. Private Sub backwk_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles backwk.DoWork
    9. Try
    10. TextBox1.Text = "Test"
    11. Catch ex As Exception
    12. MsgBox(ex.Message)
    13. End Try
    14. End Sub
    15. Private Sub backwk_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles backwk.RunWorkerCompleted
    16. End Sub
    17. End Class
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

    Das weiß ich, ich möcht wissen wieso die Exception nur beim Debugging auftritt und nicht beim ausführen der EXE.
    Ich hab ja extra versucht diesen Fehler zu provozieren indem ich das so geschrieben hab.

    Probier es mal aus. Ist ja nicht viel Code.

    War das schon immer so, oder hab ich irgendwas an den Einstellungen verstellt?
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

    Eben nicht beim release zeigt es keine MessageBox an...
    Sondern in der TextBox steht "Test", was ich eigentlich für unmöglich hielt...

    Also nochmal für Personen die schwer von Begriff sind: ;)
    Debugging: Messagebox mit Exception "ungültiger thread zugriff blabla"
    Release: In der TextBox steht "Test"

    Ich möcht wissen; war das schon immer so?, oder hab ich was verstellt?


    //EDIT:

    Ok hab die Lösung gefunden.

    stackoverflow.com/questions/39…e-running-exe-in-bin-debu

    Wenn diese Shared Property auf True gesetzt wird, dann kommt die Exception auch im Release, so möchte ich das haben :)

    VB.NET-Quellcode

    1. Control.CheckForIllegalCrossThreadCalls = TRUE
    "Es ist absolut möglich, dass jenseits der Wahrnehmung unserer Sinne ungeahnte Welten verborgen sind." — Albert Einstein
    "Wenn die Macht der Liebe die Liebe zur Macht übersteigt, erst dann wird die Welt endlich wissen, was Frieden heißt." — Jimi Hendrix

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „FredM“ ()