Wie "returne" ich ein DataTable?

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Wie "returne" ich ein DataTable?

    Hi!

    Ich hab eine Funktion die mir ein DataTable zurück geben soll..leider kommt immer "Nothing" bei raus..die Schreibfunktion funktioniert!

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class DataTable_Tools
    2. Public Shared Async Sub SaveDataTable(FileName As String, _DataTable As DataTable)
    3. Await Task.Run(Sub()
    4. DataTable_Tools.File_WaitReadWriteReady(FileName, False)
    5. End Sub).ContinueWith(Sub()
    6. DataTable_Tools.Save_DataTable_ToFile(_DataTable, FileName)
    7. End Sub)
    8. End Sub
    9. Public Shared Function ReadDataTable(FileName As String) As DataTable
    10. Task.Run(Sub()
    11. DataTable_Tools.File_WaitReadWriteReady(FileName, True)
    12. End Sub).ContinueWith(Function()
    13. Return DataTable_Tools.Load_DataTable_FromFile(FileName).Copy
    14. End Function)
    15. End Function
    16. Public Shared Sub File_WaitReadWriteReady(ByVal fileName As String, ByVal Read As Boolean)
    17. While True
    18. Try
    19. If Read Then
    20. Using stream As FileStream = New FileStream(fileName, IO.FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read)
    21. If stream IsNot Nothing Then
    22. Trace.WriteLine("Output file ready.")
    23. stream.Close()
    24. Exit While
    25. End If
    26. End Using
    27. Else
    28. Using stream As FileStream = New FileStream(fileName, IO.FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)
    29. If stream IsNot Nothing Then
    30. Trace.WriteLine("Output file ready.")
    31. stream.Close()
    32. Exit While
    33. End If
    34. End Using
    35. End If
    36. Catch ex As FileNotFoundException
    37. Trace.WriteLine(String.Format("Output file {0} not yet ready ({1})", fileName, ex.Message))
    38. Catch ex As IOException
    39. Trace.WriteLine(String.Format("Output file {0} not yet ready ({1})", fileName, ex.Message))
    40. Catch ex As UnauthorizedAccessException
    41. Trace.WriteLine(String.Format("Output file {0} not yet ready ({1})", fileName, ex.Message))
    42. Catch ex As Exception
    43. Trace.WriteLine(ex.Message)
    44. End Try
    45. Application.DoEvents()
    46. Thread.Sleep(50)
    47. End While
    48. End Sub
    49. Public Shared Function Save_DataTable_ToFile(ByVal Table As DataTable, ByVal FileName As String) As Boolean
    50. Try
    51. Using stream = New MemoryStream()
    52. Dim formatter As IFormatter = New BinaryFormatter()
    53. formatter.Serialize(stream, Table)
    54. stream.Close()
    55. Using _stream As FileStream = New FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)
    56. _stream.Write(stream.ToArray, 0, stream.ToArray.Length)
    57. End Using
    58. End Using
    59. Return True
    60. Catch ex As Exception
    61. Debug.WriteLine(ex.Message)
    62. Return False
    63. End Try
    64. End Function
    65. Public Shared Function Load_DataTable_FromFile(ByVal FileName As String) As DataTable
    66. Try
    67. Using _stream As FileStream = New FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read)
    68. Dim formatter As IFormatter = New BinaryFormatter()
    69. Return CType(formatter.Deserialize(_stream), DataTable)
    70. End Using
    71. Catch ex As Exception
    72. Debug.WriteLine(ex.Message)
    73. Return Nothing
    74. End Try
    75. End Function
    76. End Class



    dt_MainTable = DataTable_Tools.ReadDataTable(DT_MainTable_DateiName)
    Schalt mal bitte alle Schalter auf scharf. Dann siehst Du, dass die eigentliche Funktion gar keinen Wert zurückgibt, sondern nur die innere, weil Visual Studio endlich anfängt zu meckern. Die innere Funktion hat ja keinen Einfluss auf den Returnwert der äußeren. Sollte spätestens dann klar werden, wenn der Rückgabetyp der inneren ein anderer ist als der der äußeren. Du musst also den Rückgabewert der äußeren an den der inneren anbinden.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Morrison schrieb:

    Ich hab eine Funktion die mir ein DataTable zurück geben soll..leider kommt immer "Nothing" bei raus..die Schreibfunktion funktioniert!

    Meinst du dieses?

    VB.NET-Quellcode

    1. Public Shared Function Load_DataTable_FromFile(ByVal FileName As String) As DataTable
    2. Try
    3. Using _stream As FileStream = New FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read)
    4. Dim formatter As IFormatter = New BinaryFormatter()
    5. Return CType(formatter.Deserialize(_stream), DataTable)
    6. End Using
    7. Catch ex As Exception
    8. Debug.WriteLine(ex.Message)
    9. Return Nothing
    10. End Try
    11. End Function
    Naja - ist doch offensichtlich, warum die Nothing zurückgibt - schau bitte mal hin.
    TryCatch ist ein heißes Eisen



    Was ist das überhaupt für eine abenteuerliche Konstruktion mit dem ContinueWith?
    Ich weiss nicht was das macht, und wüsste nicht, wozu das gut sein soll. Weisst du's? Und bist du sicher, dass man das nicht einfach weglassen kann?

    Jedenfalls zum Testen würde ich diese Konstruktion nicht nehmen, sondern nimm einen normalen Aufruf.
    Da fällt mir auf: Application.DoEvents() Einer der Klassiker für: wie-kannst-Du-nur?!? :P


    VB.NET-Quellcode

    1. Catch ex As FileNotFoundException
    2. Trace.WriteLine(String.Format("Output file {0} not yet ready ({1})", fileName, ex.Message))
    3. Catch ex As IOException
    4. Trace.WriteLine(String.Format("Output file {0} not yet ready ({1})", fileName, ex.Message))
    5. Catch ex As UnauthorizedAccessException
    6. Trace.WriteLine(String.Format("Output file {0} not yet ready ({1})", fileName, ex.Message))

    ->

    VB.NET-Quellcode

    1. Catch ex As Exception When ex.GetType Is GetType(IO.FileNotFoundException) OrElse ex.GetType Is GetType(IO.IOException) OrElse ex.GetType Is GetType(UnauthorizedAccessException)
    2. Trace.WriteLine(String.Format("Output file {0} not yet ready ({1})", fileName, ex.Message))
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    leicht of topic:
    Ich würde die Function eher "Get_DataTable_FromFile" (ohne Unterstriche), da man ja einen Rückgabewert bekommt.
    Bei "Load_DataTable_FromFile" würde ich eher eine Sub erwarten.
    OK die "Try..Catch" hab ich bei "Save_DataTable_ToFile" und "Load_DataTable_FromFile" raus genommen..
    ..und des "Application.DoEvents()" hab ich auch gelöscht..hatte ich noch von wo ich kein extra Task hatte!

    Nun zu der Funktion "ReadDataTable"....
    ​Du musst also den Rückgabewert der äußeren an den der inneren anbinden.
    ..OK, klingt plausibel ^^ .. :/
    Also nen Rückgabewert wie "Task(Of DataTable)"? Aber wie binde ich des zusammen?

    Des sieht mir auch Falsch aus, weil auf das beenden des Tasks ja nicht gewartet wird:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Shared Function ReadDataTable(FileName As String) As DataTable
    2. Dim _dt As DataTable = New DataTable
    3. Task.Run(Sub()
    4. DataTable_Tools.File_WaitReadWriteReady(FileName, True)
    5. End Sub).ContinueWith(Sub()
    6. _dt = DataTable_Tools.Load_DataTable_FromFile(FileName).Copy
    7. End Sub)
    8. Return _dt
    9. End Function

    Morrison schrieb:

    OK die "Try..Catch" hab ich bei "Save_DataTable_ToFile" und "Load_DataTable_FromFile" raus genommen..
    ..und des "Application.DoEvents()" hab ich auch gelöscht..hatte ich noch von wo ich kein extra Task hatte!
    Und? - löst das das Problem, dass Nothing returnt wird?
    Das war doch das Problem, für welches du diesen Thread eröffnet hattest, odr?

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

    da macht er mir jetzt

    VB.NET-Quellcode

    1. Public Shared Async Function ReadDataTable(FileName As String) As Task(Of DataTable)
    2. Await Task.Run(Sub()
    3. DataTable_Tools.File_WaitReadWriteReady(FileName, True)
    4. End Sub)
    5. Return DataTable_Tools.Load_DataTable_FromFile(FileName).Copy
    6. End Function


    draus..
    ..und wie gehe ich jetzt mit dem "Task(Of DataTable)" um?

    aah, ok: dt_MainTable = Await Tools.Tools.DataTable_Tools.ReadDataTable(DT_MainTable_DateiName)


    Käy, scheint zu funktionieren! ;)Danke!!
    Hmm,

    kann mir zufällig jemand sagen ob diese Anordnung überhaupt funktioniert!
    Also Ziel ist es ja eig. in der "while"-Schleife so lange zu warten bis die Datei verfügbar ist, also nicht mehr "locked" ist.

    Für mich sieht es aber so aus als wäre es möglich nach dem Aufruf von "File_WaitReadWriteReady" einen fremden Dateizugriff zu starten!

    Hab schon probiert nen "FileStream" mit zu übergeben, bzw zu "returnen", aber des bekomm ich nicht hin das ganze durchreichen..zumal ich das dann ja auch wieder "disposen" muss!
    Naja, den von oben:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class DataTable_Tools
    2. Public Shared Async Sub SaveDataTable(FileName As String, _DataTable As DataTable)
    3. Await Task.Run(Sub()
    4. DataTable_Tools.File_WaitReadWriteReady(FileName, False)
    5. End Sub)
    6. DataTable_Tools.Save_DataTable_ToFile(_DataTable, FileName)
    7. End Sub
    8. Public Shared Async Function ReadDataTable(FileName As String) As Task(Of DataTable)
    9. Await Task.Run(Sub()
    10. DataTable_Tools.File_WaitReadWriteReady(FileName, True)
    11. End Sub)
    12. Return DataTable_Tools.Load_DataTable_FromFile(FileName).Copy
    13. End Function
    14. Public Shared Sub File_WaitReadWriteReady(ByVal fileName As String, ByVal Read As Boolean)
    15. While True
    16. Try
    17. If Read Then
    18. Using stream As FileStream = New FileStream(fileName, IO.FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read)
    19. If stream IsNot Nothing Then
    20. Trace.WriteLine("Output file ready.")
    21. 'stream.Close()
    22. Exit While
    23. End If
    24. End Using
    25. Else
    26. Using stream As FileStream = New FileStream(fileName, IO.FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)
    27. If stream IsNot Nothing Then
    28. Trace.WriteLine("Output file ready.")
    29. 'stream.Close()
    30. Exit While
    31. End If
    32. End Using
    33. End If
    34. Catch ex As Exception When ex.GetType Is GetType(IO.FileNotFoundException) OrElse ex.GetType Is GetType(IO.IOException) OrElse ex.GetType Is GetType(UnauthorizedAccessException)
    35. Trace.WriteLine(String.Format("Output file {0} not yet ready ({1})", fileName, ex.Message))
    36. Catch ex As Exception
    37. Trace.WriteLine(ex.Message)
    38. End Try
    39. Thread.Sleep(50)
    40. End While
    41. End Sub
    42. Private Shared Sub Save_DataTable_ToFile(ByVal Table As DataTable, ByVal FileName As String)
    43. Using stream = New MemoryStream()
    44. Dim formatter As IFormatter = New BinaryFormatter()
    45. formatter.Serialize(stream, Table)
    46. stream.Close()
    47. Using fs As FileStream = New FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)
    48. fs.Write(stream.ToArray, 0, stream.ToArray.Length)
    49. End Using
    50. End Using
    51. End Sub
    52. Private Shared Function Load_DataTable_FromFile(ByVal FileName As String) As DataTable
    53. Using fs As FileStream = New FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read)
    54. Dim formatter As IFormatter = New BinaryFormatter()
    55. Return CType(formatter.Deserialize(fs), DataTable)
    56. End Using
    57. End Function
    58. End Class
    59. End Class



    Also praktisch die "SaveDataTable" und "ReadDataTable"
    Ah - ich würd eher was einfacheres versuchen:

    VB.NET-Quellcode

    1. Private Shared Sub Save_DataTable_ToFile(ByVal Table As DataTable, ByVal FileName As String)
    2. For i = 0 To 99
    3. Try
    4. Using stream = New FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)
    5. Dim formatter = New BinaryFormatter()
    6. formatter.Serialize(stream, Table)
    7. End Using
    8. Return
    9. Catch ex As Exception
    10. Thread.Sleep(50)
    11. End Try
    12. Next
    13. Throw New InvalidOperationException($"100 tryals failed to save {FileName}")
    14. End Sub
    Das kannste Async aufrufen und gut.
    Den Catch empfehle ich ausdifferenzieren auf die wirklich zu erwartenden Exceptions.