Rückgabewert eines Threads in einer .dll

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von .Scare.

    Rückgabewert eines Threads in einer .dll

    Hallo Com.

    Ich weis nicht ob ich einfacht nur auf dem Schlach stehe oder ob dies wirklich nicht so einfacht geht.

    Ich habe mein Hauptprojekt und darin eine .DLL

    vom Hauptprogramm aus starte ich eine Sub in der DLL in einem Thread. nun aber die Frage, wie bekomme ich das Resultat dieser Sub in das Hauptprogramm?

    Und ja, ich muss leider diese Sub in einem Thread laufen lassen, da diese eine Xml-Datei ausliest und weiter verarbeitet welche mehr als 4000 Zeilen hat... =(
    Was für ein Resultat? Eine Sub hat keinen Rückgabewert...
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    hups, falsche ausgedrückt. das Resultat ist in einer Variable z.b. Result_Text As String und diesen möchte ich irgendwie in meine MainClass weitergeben.

    Ich habe mir schon überlegt das Resultat im Temp zwischen zu speichern und nach dem beenden des threades von der MainClass wider auszulesen..

    aber ihc denke fast das es eigentlich noch etwas schöner geht oder nicht?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „.Scare“ ()

    Im Normalfall sieht das in etwa so aus:
    Spoiler anzeigen
    Hauptprogramm:

    VB.NET-Quellcode

    1. Sub StartDoingStuff()
    2. With New Thread( _
    3. Sub()
    4. Dim Doer As New Dll.StuffDoer
    5. Dim Result = Doer.DoStuff()
    6. 'Was mit Result machen
    7. End Sub)
    8. .Start()
    9. End With
    10. End Sub
    Dll:

    VB.NET-Quellcode

    1. Public Class StuffDoer
    2. Public Function DoStuff() As DoStuffResult
    3. '...
    4. End Function
    5. End Class

    Oder, wenn die Methode das nicht direkt zurückgibt, sondern in eine Variable speichert:
    Spoiler anzeigen
    Hauptprogramm:

    VB.NET-Quellcode

    1. Sub StartDoingStuff()
    2. With New Thread( _
    3. Sub()
    4. Dim Doer As New Dll.StuffDoer
    5. Doer.DoStuff()
    6. Dim Result = Doer.Result
    7. 'Was mit Result machen
    8. End Sub)
    9. .Start()
    10. End With
    11. End Sub
    Dll:

    VB.NET-Quellcode

    1. Public Class StuffDoer
    2. Public Property Result As DoStuffResult
    3. Public Sub DoStuff()
    4. '...
    5. Result = ...
    6. End Sub
    7. End Class


    Wie sieht das bei Dir aus? Wie sehen die entsprechenden Klassen aus?
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Niko Ortner schrieb:

    Im Normalfall sieht das in etwa so aus:
    Spoiler anzeigen
    Hauptprogramm:

    VB.NET-Quellcode

    1. Sub StartDoingStuff()
    2. With New Thread( _
    3. Sub()
    4. Dim Doer As New Dll.StuffDoer
    5. Dim Result = Doer.DoStuff()
    6. 'Was mit Result machen
    7. End Sub)
    8. .Start()
    9. End With
    10. End Sub
    Dll:

    VB.NET-Quellcode

    1. Public Class StuffDoer
    2. Public Function DoStuff() As DoStuffResult
    3. '...
    4. End Function
    5. End Class

    Oder, wenn die Methode das nicht direkt zurückgibt, sondern in eine Variable speichert:
    Spoiler anzeigen
    Hauptprogramm:

    VB.NET-Quellcode

    1. Sub StartDoingStuff()
    2. With New Thread( _
    3. Sub()
    4. Dim Doer As New Dll.StuffDoer
    5. Doer.DoStuff()
    6. Dim Result = Doer.Result
    7. 'Was mit Result machen
    8. End Sub)
    9. .Start()
    10. End With
    11. End Sub
    Dll:

    VB.NET-Quellcode

    1. Public Class StuffDoer
    2. Public Property Result As DoStuffResult
    3. Public Sub DoStuff()
    4. '...
    5. Result = ...
    6. End Sub
    7. End Class


    Wie sieht das bei Dir aus? Wie sehen die entsprechenden Klassen aus?


    Vielen dank für deine Hilfreiche Antwort!

    Ich habe den aufruf so:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub btn_convert_convert_Click(sender As Object, e As EventArgs) Handles btn_convert_convert.Click
    2. With New Thread(Sub()
    3. Dim converter As New Converter.Convert
    4. Dim Result As String = converter.Verarbeite(Application.StartupPath & "\item.xml")
    5. MsgBox(Result)
    6. End Sub)
    7. .Start()
    8. End With
    9. End Sub


    und die DLL sieht so aus:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Xml
    2. Imports System.IO
    3. Public Class Convert
    4. Public _
    5. _vnum, _name, _gb2312name, _type, _subtype, _weight, _size, _antiflag, _
    6. _flag, _wearflag, _immuneflag, _gold, _buy_price, _limittype0, _limitvalue0, _
    7. _limittype1, _limitvalue1, _applytype0, _applyvalue0, _applytype1, _applyvalue1, _
    8. _applytype2, _applyvalue2, _value0, _value1, _value2, _value3, _value4, _value5, _
    9. _socket0, _socket1, _socket2, _socket3, _socket4, _socket5, _refine_vnum, _
    10. _refine_set, _magic_pct, _specular, _socket_pct _
    11. As String
    12. Public convertet_Text As String
    13. Public zeile As Integer = 0
    14. Public Function Verarbeite(Path As String) As String
    15. Try
    16. Dim document As New XmlDocument
    17. document.Load(Path)
    18. Dim documentElement As XmlElement = document.DocumentElement
    19. Dim node As XmlNode
    20. Dim max_zeile As Integer = documentElement.ChildNodes.Count
    21. For Each node In documentElement.ChildNodes
    22. _vnum = node.Attributes.ItemOf("vnum").InnerText
    23. _name = node.Attributes.ItemOf("name").InnerText.Replace("'", "")
    24. _gb2312name = node.Attributes.ItemOf("gb2312name").InnerText
    25. _type = node.Attributes.ItemOf("type").InnerText
    26. _subtype = node.Attributes.ItemOf("subtype").InnerText
    27. _weight = node.Attributes.ItemOf("weight").InnerText
    28. _size = node.Attributes.ItemOf("size").InnerText
    29. _antiflag = node.Attributes.ItemOf("antiflag").InnerText
    30. _flag = node.Attributes.ItemOf("flag").InnerText
    31. _wearflag = node.Attributes.ItemOf("wearflag").InnerText
    32. _immuneflag = node.Attributes.ItemOf("immuneflag").InnerText
    33. _gold = node.Attributes.ItemOf("gold").InnerText
    34. _buy_price = node.Attributes.ItemOf("buy_price").InnerText
    35. _limittype0 = node.Attributes.ItemOf("limittype0").InnerText
    36. _limitvalue0 = node.Attributes.ItemOf("limitvalue0").InnerText
    37. _limittype1 = node.Attributes.ItemOf("limittype1").InnerText
    38. _limitvalue1 = node.Attributes.ItemOf("limitvalue1").InnerText
    39. _applytype0 = node.Attributes.ItemOf("applytype0").InnerText
    40. _applyvalue0 = node.Attributes.ItemOf("applyvalue0").InnerText
    41. _applytype1 = node.Attributes.ItemOf("applytype1").InnerText
    42. _applyvalue1 = node.Attributes.ItemOf("applyvalue1").InnerText
    43. _applytype2 = node.Attributes.ItemOf("applytype2").InnerText
    44. _applyvalue2 = node.Attributes.ItemOf("applyvalue2").InnerText
    45. _value0 = node.Attributes.ItemOf("value0").InnerText
    46. _value1 = node.Attributes.ItemOf("value1").InnerText
    47. _value2 = node.Attributes.ItemOf("value2").InnerText
    48. _value3 = node.Attributes.ItemOf("value3").InnerText
    49. _value4 = node.Attributes.ItemOf("value4").InnerText
    50. _value5 = node.Attributes.ItemOf("value5").InnerText
    51. _socket0 = node.Attributes.ItemOf("socket0").InnerText
    52. _socket1 = node.Attributes.ItemOf("socket1").InnerText
    53. _socket2 = node.Attributes.ItemOf("socket2").InnerText
    54. _socket3 = node.Attributes.ItemOf("socket3").InnerText
    55. _socket4 = node.Attributes.ItemOf("socket4").InnerText
    56. _socket5 = node.Attributes.ItemOf("socket5").InnerText
    57. _refine_vnum = node.Attributes.ItemOf("refine_vnum").InnerText
    58. _refine_set = node.Attributes.ItemOf("refine_set").InnerText
    59. _magic_pct = node.Attributes.ItemOf("magic_pct").InnerText
    60. _specular = node.Attributes.ItemOf("specular").InnerText
    61. _socket_pct = node.Attributes.ItemOf("socket_pct").InnerText
    62. zeile += 1
    63. convertet_Text = String.Concat(New String() {convertet_Text, "INSERT INTO'item_proto' VALUES ('", _vnum, _
    64. "', '", _name, _
    65. "', '", _gb2312name, _
    66. "', '", _type, _
    67. "', '", _subtype, _
    68. "', '", _weight, _
    69. "', '", _size, _
    70. "', '", _antiflag, _
    71. "', '", _flag, _
    72. "', '", _wearflag, _
    73. "', '", _immuneflag, _
    74. "', '", _gold, _
    75. "', '", _buy_price, _
    76. "', '", _limittype0, _
    77. "', '", _limitvalue0, _
    78. "', '", _limittype1, _
    79. "', '", _limitvalue1, _
    80. "', '", _applytype0, _
    81. "', '", _applyvalue0, _
    82. "', '", _applytype1, _
    83. "', '", _applyvalue1, _
    84. "', '", _applytype2, _
    85. "', '", _applyvalue2, _
    86. "', '", _value0, _
    87. "', '", _value1, _
    88. "', '", _value2, _
    89. "', '", _value3, _
    90. "', '", _value4, _
    91. "', '", _value5, _
    92. "', '", _socket0, _
    93. "', '", _socket1, _
    94. "', '", _socket2, _
    95. "', '", _socket3, _
    96. "', '", _socket4, _
    97. "', '", _socket5, _
    98. "', '", _refine_vnum, _
    99. "', '", _refine_set, _
    100. "', '", _magic_pct, _
    101. "', '", _specular, _
    102. "', '", _socket_pct, "');" & ChrW(13) & ChrW(10)})
    103. Next
    104. Catch ex As Exception
    105. MsgBox(ex.Message)
    106. Finally
    107. End Try
    108. Return convertet_Text.ToString()
    109. End Function
    110. End Class


    So wie es jetzt ist, gibt es keinen Fehler zurück und es läst sich supper starten. aber ich bekomme eine:

    Quellcode

    1. Eine Ausnahme (erste Chance) des Typs "System.NullReferenceException" ist in Converter.dll aufgetreten.


    Der Path den ich angebe stimmt allerdings und die Datei ist auch da.
    Der Aufruf sieht prinzipiell OK aus. Eventuell solltest Du System.IO.Path.Combine() verwenden, um den Pfad zusammenzustellen.

    Bei der Dll sieht's nicht so rosig aus.
    Ist die von Dir? Wenn ja, schreib sie um. Kapselung! Felder sollten fast nie public sein. Kapsle die Daten in eine eigene Klasse (ich nehme an, das soll ein Produkt sein, also Class Product) und verwende Properties für alles, was public sein muss.

    Als nächstes solltest Du das TryCatch rausnehmen. Vor allem sollte in einer Dll niemals sowas wie MsgBox oder MessageBox.Show drin stehen. Prüfe die Daten auf Gültigkeit und wirf, wenn es Probleme gibt, eine eigene Exception.

    Das Zusammenstellen des SQL-Befehls ist eine riesige Sicherheitslücke.
    vb-paradise.de/index.php/Thread/?postID=768621#post768621
    Trenne das Auslesen aus der Xml-Datei vom Datenbankzugriff.

    convertet_Text.ToString()

    Welchen Datentyp hat convertet_Text?
    Und was macht wohl die Funktion ToString()?
    Na? Merkste selber, 'ne?
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Und auch hier frage ich: Warum nutzt du 2000 Variablen, anstatt einer List<> ?

    VB.NET-Quellcode

    1. Dim result As New List(Of String)
    2. Dim fields As String() = {"vnum", "name", ... , "socket_pct"}
    3. For Each ...
    4. For Each field As String in String()
    5. result.Add(node.Attributes.ItemOf(field).InnerText)
    6. Next
    7. convertet_Text = String.Concat(convertet_Text, String.Join("', '", result))
    8. Next
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

    Niko Ortner schrieb:

    Als nächstes solltest Du das TryCatch rausnehmen


    Dies hatte ich drin damit es mir bei einem Fehler die Exeption Message anzeigt. =)

    Niko Ortner schrieb:

    Vor allem sollte in einer Dll niemals sowas wie MsgBox oder MessageBox.Show drin stehen.

    Dies habe ich natürlich nur zur überprüffung drin damit ich weis was wann wie herauskommt.

    Niko Ortner schrieb:

    Das Zusammenstellen des SQL-Befehls ist eine riesige Sicherheitslücke.

    Keine sorge, ich erstelle nur eine Datei.SQL, welche man von hand selber über Navicat der DB einspielen soll. ich verbinde mit keiner Datenbank oder sonstigem.

    Niko Ortner schrieb:

    Welchen Datentyp hat convertet_Text?
    Und was macht wohl die Funktion ToString()?
    Na? Merkste selber, 'ne?

    :P ja, da habe ich etwas rumprobiert ob allenfals da ein Fehler sein könnte oder nicht. logischerweise ist convertet_Text ja shcon ein String :P

    ThePlexian schrieb:

    Und auch hier frage ich: Warum nutzt du 2000 Variablen, anstatt einer List<> ?

    Weil ich mit den Listen so ein Problem habe =) die mögen mich nicht und ich Sie nicht xD

    VB.NET-Quellcode

    1. Dim result As New List(Of String)
    2. Dim fields As String() = {"vnum", "name", ... , "socket_pct"}
    3. For Each ...
    4. For Each field As String in String()
    5. result.Add(node.Attributes.ItemOf(field).InnerText)
    6. Next
    7. convertet_Text = String.Concat(convertet_Text, String.Join("', '", result))
    8. Next



    Verstehe ich das richtig? Bei deinem Beispiel müsste ich mit der Ersten For Each die Linien in der xml durchlaufen.
    und mit der 2ten in der ersten drin, die einzelnen felder?

    danke für eure Hilfestellungen


    Edit:

    So, ich habe mal einiges versucht, aber es will und wil nicht gehen. irgentwas übersehe ich.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Xml
    2. Imports System.IO
    3. Public Class Convert
    4. Dim result As New List(Of String)
    5. Dim fields As String() = {"vnum", "name", "gb2312name", "type", "subtype", "weight", "size", "antiflag", _
    6. "flag", "wearflag", "immuneflag", "gold", "buy_price", "limittype0", "limitvalue0", _
    7. "limittype1", "limitvalue1", "applytype0", "applyvalue0", "applytype1", "applyvalue1", _
    8. "applytype2", "applyvalue2", "value0", "value1", "value2", "value3", "value4", "value5", _
    9. "socket0", "socket1", "socket2", "socket3", "socket4", "socket5", "refine_vnum", _
    10. "refine_set", "magic_pct", "specular", "socket_pct"}
    11. Public convertet_Text As String
    12. Public Function Verarbeite(Path As String) As String
    13. Dim document As New XmlDocument
    14. document.Load(Path)
    15. Dim documentElement As XmlElement = document.DocumentElement
    16. Dim node As XmlNode
    17. Dim max_zeile As Integer = documentElement.ChildNodes.Count
    18. For Each line As Xml.XmlNode In documentElement.ChildNodes ''''/// was muss ich hier Durchlafen????
    19. For Each field As String In line ''''///Was muss ich hier durchlaufen????
    20. result.Add(node.Attributes.ItemOf(field).InnerText)
    21. MsgBox(result)
    22. Next
    23. convertet_Text = String.Concat(convertet_Text, String.Join("', '", result))
    24. Next
    25. Return convertet_Text
    26. End Function
    27. End Class


    Ich "Peile" gerade nicht ganz wie ich die For Each schleiffen füttere.

    Niko Ortner schrieb:

    nzipiell OK aus. Eventuell solltest Du System.IO.Path.Combine() verwenden, um den Pfad zusammenzustellen.Bei der Dll sieht's nicht so rosig aus.Ist die von Dir? Wenn ja, schreib sie um. Kapselung! Felder sollten fast nie public sein. Kapsle die Daten in eine eigene Klasse (ich nehme an, das soll ein Produkt sein, also Class Product) und verwende Properties für alles, was public sein muss.


    Denkst du das es so in die Richtung besser wäre, wen es dann laufen tut

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „.Scare“ ()

    Die MessageBox macht nichts anderes, als Dir die Debug-Möglichkeit zu nehmen.
    NullReference-Exeption

    Keine sorge, ich erstelle nur eine Datei.SQL
    Das macht in diesem Fall keinen Unterschied. Ich glaube kaum, dass Du Dir von Hand nochmal alles durchliest, bevor Du das SQL-Script ausführst.
    Da muss nur jemand '); DROP TABLE item_proto; -- in die Xml-Datei schreiben und die Tabelle ist futsch.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    hihi, ja gut. da hast du schon recht, aber dieses Tool benutzt der, der die Datei benötigt. wen er lust hast Drop table zu schreiben dan ist er selberschuld. :P

    andere Frage, das Beispiel von @ThePlexian

    verstehst du was er meinte mit den beiden For Ech schleifen? ich blicke gerade nicht ganz durch was ich durchlaufen müsste damit.
    Du hast sooo viele String Variablen. Anstattdessen, nimmst du eine List<String>. Parallel dazu, hast du ein Array, wo alle deine Felder drin sind (also die du als String beim auslesen angibst). Durch das Array iterierst du, und addest jeweils den Text in die List. Wie mein Code halt andeutet.

    Ja ist doch richtig so ^^ Nur das MsgBox(List<T>) nicht geht.
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ThePlexian“ ()

    Ach so, ich Affe habe da etwas falsch verstanden... habe es nun so gemacht wie du Beschrieben hast... wen man es nun so ansieht hätte ich eigentlich auch selber drauf kommen können. =)

    Vielen Vielen dank für die Rasche und gute Hilfe an euch 2!!

    Somit hat es sich für mich erledigt in diesem Thema. =)