FTP-Webrequest Codeoptimierung

  • VB.NET

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

    FTP-Webrequest Codeoptimierung

    Hallo,

    Ich arbeite gerade an einem FTP Up/Download Programm, es funkrioniert ganz gut, aber da ich noch eine "unsaubere" schreibweise habe, fände ich es nett, wenn ihr mir sagen würdet was ich noch ausbessern kann bzw. wie es sauberer wäre. Das Programm ist noch nicht ganz fertig, kommt noch eine voraussichtliche Restzeit Rechnung rein. Aber wenn ich was ändern sollte dann lieber jetzt als später.

    VB.NET-Quellcode

    1. Public Class frmUpload
    2. Private Class Upload_Args
    3. Public file_name As String
    4. Public file_path As String
    5. Public server_address As String
    6. Public user_name As String
    7. Public password As String
    8. Public Sub New(ByVal f_n As String, ByVal p_a As String, ByVal s_a As String, ByVal user As String, ByVal pass As String)
    9. file_name = f_n
    10. file_path = p_a
    11. server_address = s_a
    12. user_name = user
    13. password = pass
    14. End Sub
    15. End Class
    16. Dim t As Threading.Thread
    17. Dim password As String
    18. Dim user As String
    19. Dim server_address As String
    20. Private Delegate Sub Updating(ByVal rest_bytes As Integer, ByVal file_lenght As Integer, ByVal done As Boolean)
    21. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    22. Using ofd As New OpenFileDialog
    23. ofd.Multiselect = False
    24. If ofd.ShowDialog <> Windows.Forms.DialogResult.OK Then
    25. Return
    26. End If
    27. Dim ofd_path As String = ofd.FileName.Substring(0, ofd.FileName.LastIndexOf("\") + 1)
    28. Dim ofd_file As String = IO.Path.GetFileName(ofd.FileName)
    29. Dim args As New Upload_Args(ofd_file, ofd_path, server_address, user, password)
    30. Dim tS As New Threading.ParameterizedThreadStart(AddressOf Upload)
    31. Dim t As New Threading.Thread(tS)
    32. t.Start(args)
    33. End Using
    34. End Sub
    35. Private Sub Upload(ByVal arguments As Object)
    36. Dim args As Upload_Args = DirectCast(arguments, Upload_Args)
    37. Dim request As System.Net.FtpWebRequest = DirectCast(System.Net.WebRequest.Create(args.server_address & args.file_name), System.Net.FtpWebRequest)
    38. request.Credentials = New System.Net.NetworkCredential(args.user_name, args.password)
    39. request.Method = System.Net.WebRequestMethods.Ftp.UploadFile
    40. Dim strz As System.IO.Stream = request.GetRequestStream()
    41. Dim rest As Integer
    42. Dim full_lenght As Integer
    43. Using fileStream As New IO.FileStream(args.file_path & args.file_name, IO.FileMode.Open, IO.FileAccess.Read)
    44. rest = CInt(fileStream.Length)
    45. full_lenght = rest
    46. Dim buffer(31) As Byte
    47. Dim bytesRead As Integer = fileStream.Read(buffer, 0, buffer.Length)
    48. Do While (bytesRead > 0)
    49. strz.Write(buffer, 0, bytesRead)
    50. bytesRead = fileStream.Read(buffer, 0, buffer.Length)
    51. rest -= buffer.Length
    52. Me.Invoke(New Updating(AddressOf Upload_State), rest, full_lenght, False)
    53. Loop
    54. End Using
    55. strz.Close()
    56. strz.Dispose()
    57. Me.Invoke(New Updating(AddressOf Upload_State), rest, full_lenght, True)
    58. End Sub
    59. Private Sub Upload_State(ByVal rest_bytes As Integer, ByVal file_lenght As Integer, ByVal done As Boolean)
    60. If done Then
    61. If MessageBox.Show("Upload abgeschlossen", "Uploader", MessageBoxButtons.OK) = Windows.Forms.DialogResult.OK Then
    62. Application.Exit()
    63. End If
    64. Else
    65. Dim uploaded_percent As Double = ((rest_bytes / file_lenght * 100) - 100) * -1
    66. ProgressBar1.Value = CInt(uploaded_percent)
    67. End If
    68. End Sub
    69. End Class


    mfG

    Derfuhr
    Der buffer ist mit Größe 32 wohl ein Witz. jmd. hat mal rumgetestet, und fund ein Leistungs-Optimum in der Gegend einer BufSize von 1024.
    (Hat mich gewundert, denn ich hätte gedacht, je größer der Buffer, desto besser)

    und möglichst immer Control.BeginInvoke verwenden statt Control.Invoke.
    Noch besser wäre ein Mechanismus, der dafür sorgt, dass die Progressbar nicht häufiger als alle 300ms aktualisiert wird - das reicht nämlich völlig.
    Hallo ErfinderDesRades,

    danke das du dir die Zeit genommen hast den Code in Augenschein zu nehmen. Ist der Unterschied zwischen .Invoke() und .BeginInvike() nur das mit .BeginInvoke() der Delegat asyncron für den Thread in dem das Handle für das Steuerelement erstellt wurde ausführt wird? Mit der kleinen Buffergröße habe ich gedacht, das ich die zu verbleibenden Bytes(später auch vorrauss. Restzeit) exakter berechnen kann, da ich nur Audio-Dateien <10MB pro Datei auf diesem Server lagern werde.
    Aber das mit dem Progressbar Updaten ist ein sehr guter Tipp um die Performence des Programs zu steigern(sind sicher Typische Amateur Fehler). Da dieses Program später wenn´s fertig ist in meinem Bass.dll Mediaplayer eingebaut wird habe ich nun noch Fragen. Wäre es nicht besser zum anhören der Audios statt zu Downloaden nur vom Server aus zu Streamen? Da ich von Serverseitigen Programmen noch 0 Ahnung habe, stellt sich die Frage wie kann man das bewerkstelligen bzw. wie hoch wäre der Aufwand bzw. Schwierigkeitsgrad?

    mfG

    Derfuhr

    Derfuhr schrieb:

    Ist der Unterschied zwischen .Invoke() und .BeginInvike() nur das mit .BeginInvoke() der Delegat asyncron für den Thread in dem das Handle für das Steuerelement erstellt wurde ausführt wird?
    "Nur" ist gut - in diesem Falle dürfte das ziemlich was ausmachen.
    Habich jetzt mal generell erklärt: Control.Invoke() vs. .BeginInvoke()

    v.a. kostet es nichts, niente, null: Einfach BeginInvoke hinschreiben, wo vorher Invoke stund.
    Ein paar Anmerkungen:
    - Control.Invoke: die Ausführung erfolgt im GUI-Thread, der aufrufende Code wartet
    - Control.BeginInvoke: die Ausführung erfolgt im GUI-Thread, der aufrufende Code wartet nicht
    - mit einem grösseren Buffer erledigt sich jegliche Trickserei mit dem Update der Progressbar, der eigentliche Zeitaufwand besteht da eh nur im Invoke
    - überprüfe doch mal ob die Bass.dll nicht direkt das Streaming übernhemen kann -> Bass Audio Library Samples