1

さて、さまざまな方法で大きなファイルをダウンロードしようとしています。私のコードでは通常最もうまくMy.Computer.NetWork.DownloadFileいくのですが、ファイルが 1.5Gb であるため、Windows フォームがフリーズして応答しません。時間の無駄だと思ったので、5分待った後、どれくらい反応しないかを気にせずに待ちました。だから私も試しましたwc.DownloadFileAsync(wcはWebクライアントの略です)これは機能し、Windowsフォームをフリーズしませんが、これの問題はスキップしてダウンロードが完了するまで待たないため、コードを続行し、したがって、エラーが発生します。

ダウンロードが完了するまでコードを一時停止または停止する方法を調べてみましたが、うまくいきませんでした。さらに調査した結果、backgroundworker クラスを見つけました。これがうまくいくかどうか、コードにどのように実装するか、またはこれを行うためのより簡単な方法があるかどうか疑問に思っていましたか?

コードにうまく実装できませんでした。呼び出すことができなかったため、次のようなエラーが発生しました: Cross-thread operation not valid

これは現在、バックグラウンド ワーカーを使用した私のコードです。

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    Dim downloader As New System.Net.WebClient

    Dim ServerVersion = wc.DownloadString("http://127.0.0.1:8080/patch/PatchList.txt").Trim
    Dim tLines As String() = ServerVersion.Split(Environment.NewLine)
    For Each NewLine As String In tLines
        Dim tVersionAndUrl As String() = NewLine.Split(vbTab)

        Dim encText As New System.Text.UTF8Encoding()
        Dim btText() As Byte
        btText = encText.GetBytes(tVersionAndUrl(0))
        'MessageBox.Show(btText.ToString)

        'MessageBox.Show(tVersionAndUrl(0)(0))
        If tVersionAndUrl.Length < 2 Then
            Exit For
        End If
        If Integer.Parse(tVersionAndUrl(0)) < Integer.Parse(CVersion.Text) Then
            Dim TempPath As String = "\launcher\temp.rar"

            AddHandler wc.DownloadProgressChanged, AddressOf ProgressChanged
            AddHandler wc.DownloadProgressChanged, AddressOf ProgressChanged
            AddHandler wc.DownloadFileCompleted, AddressOf DownloadCompleted
            'wc.DownloadFileAsync(New Uri(tVersionAndUrl(1)), Me.GetFileName(tVersionAndUrl(1)))
            wc.DownloadFileAsync(New Uri(tVersionAndUrl(1)), tmp, Stopwatch.StartNew)
            'My.Computer.FileSystem.DeleteFile(Me.GetFileName(tVersionAndUrl(1)))


            CVersion.Text = tVersionAndUrl(0)
            LabelStatus.Text = "Download in Progress"
            Button1.Enabled = False

        End If
    Next
    MsgBox("Client is up to date")

End Sub

そして、これはそのための Addhandlers です:

    Private Sub ProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
    Dim bytesIn As Double = Double.Parse(e.BytesReceived.ToString())
    Dim totalBytes As Double = Double.Parse(e.TotalBytesToReceive.ToString())
    Dim percentage As Double = bytesIn / totalBytes * 100
    ProgressBarCurrent.Value = Int32.Parse(Math.Truncate(percentage).ToString())

    Dim BytesDownloaded As String = (e.BytesReceived / (DirectCast(e.UserState, Stopwatch).ElapsedMilliseconds / 1000.0#)).ToString("#")

    If BytesDownloaded < 1024 Then
        Dim Bs As String = Convert.ToInt32(BytesDownloaded)
        Label4.Text = (Bs & " B/s")
    ElseIf BytesDownloaded < 1048576 Then
        Dim KBs As String = Math.Round(BytesDownloaded / 1024, 2)
        Label4.Text = (KBs & " KB/s")
    ElseIf BytesDownloaded < 1073741824 Then
        Dim MBs As String = Math.Round(BytesDownloaded / 1048576, 2)
        Label4.Text = (MBs & " MB/s")
    End If

End Sub

Private Sub DownloadCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
    'MessageBox.Show("Download Complete")
    LabelStatus.Text = "Download Complete"
    Button1.Enabled = True
    Downloading = False
End Sub

助けていただければ幸いです。ありがとう。

4

2 に答える 2

0

あなたのコードでは、BackgroundWorker クラスを使用していることがわかります。私が見つけようとしているのは、ProgressChangedRunWorkerCompletedなどの BackgroundWorker クラスの残りのデリゲート関数です(代わりに、後の段階でエラーにつながる可能性のある独自のデリゲートを登録しました)。これらのイベントを処理してみてください。タスクが完了すると通知され、その間の進捗状況が報告されます。style進行状況を報告するために、メイン UI スレッドで、プロパティを に設定して進行状況バーを実行することもできますMarquee

于 2013-08-05T03:22:24.557 に答える