Backgroundworker Progressbar冻结

时间:2013-07-31 23:40:55

标签: vb.net

所以我终于得到了几乎的工作,但现在我每隔几次测试一下表格和进度条冻结的过程。我也相信有更有效的方法可以做到这一点,所以任何建设性的批评都会受到高度赞赏。

这是一个程序页面的编码,允许用户单击一个按钮下载并安装一个应用程序,然后按下一个按钮下载并安装另一个应用程序:

Imports System.Net.WebRequestMethods
Public Class Software

'Open link in external browser
Public Sub HandleRequestNavigate(ByVal sender As Object, ByVal e As RequestNavigateEventArgs)
    Process.Start(New ProcessStartInfo(e.Uri.AbsoluteUri))
    e.Handled = True
End Sub

'Declarations
Shared progressamc As New Progress
Shared progresscti As New ProgressCTI
WithEvents startcti As New Process
WithEvents startamc As New Process
WithEvents startsfstb As New Process
WithEvents amcworker As New ComponentModel.BackgroundWorker
WithEvents ctiworker As New ComponentModel.BackgroundWorker
Dim ProgressBarAMC As Object = Progress.ProgressBar1
Dim blprgrsAMC As Object = Progress.blprgrs
Dim ProgressBarCTI As Object = progresscti.ProgressBar1
Dim blprgrsCTI As Object = progresscti.blprgrs


'FTP Values
Const host As String = "ftp://10.167.16.80/"
Const username As String = "anonymous"
Const password As String = ""
'AMC File Put/Get
Const localfileamc As String = "C:\AMC.exe"
Const Remotefileamc As String = "Bin/AMC.exe"
'CTI File Put/Get
Const localfilecti As String = "C:\CTI.exe"
Const Remotefilecti As String = "Bin/CTI.exe"

'On Init
Public Sub New()
    InitializeComponent()
    amcworker.WorkerReportsProgress = True
    amcworker.WorkerSupportsCancellation = True
    ctiworker.WorkerReportsProgress = True
    ctiworker.WorkerSupportsCancellation = True
End Sub

'Install AMC Button
Private Sub ButtonAMC(sender As Object, e As RoutedEventArgs)
    Dim butt1 As Button = DirectCast(sender, Button)
    butt1.IsEnabled = False
    Dispatcher.BeginInvoke(New Action(AddressOf progressamc_Show))
    AddHandler Progress.Cancel_Click, AddressOf myProcessamc_Exited
    amcworker.RunWorkerAsync()
End Sub

'Open Dialog
Private Sub progressamc_Show()
    Try
        progressamc.ShowDialog()
    Catch ex As Exception
        MessageBox.Show("An error has occurred during the process:" & vbCrLf & vbCrLf & ex.Message & vbCrLf & vbCrLf & "Please close the application and try again." _
                & vbCrLf & "If you continue to encounter this error please Email")
    End Try
End Sub

'FTP - Download
Private Sub ftpseshamc_DoWork(ByVal sender As System.Object, ByVal e As ComponentModel.DoWorkEventArgs) Handles amcworker.DoWork
    Dim URI As String = host & Remotefileamc
    Dim FTP As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(URI), System.Net.FtpWebRequest)
    'Set the credentials
    FTP.Credentials = New System.Net.NetworkCredential(username, password)
    'FTP Options
    FTP.KeepAlive = False
    FTP.UseBinary = True
    'Define the action as Download
    FTP.Method = System.Net.WebRequestMethods.Ftp.DownloadFile
    'Get the response to the Ftp request and the associated stream
    Try
        Dim response As System.Net.FtpWebResponse = CType(FTP.GetResponse, System.Net.FtpWebResponse)
        Dim Length As Long = response.ContentLength
        Dim StopWatch As New Stopwatch
        Dim CurrentSpeed As Double = Nothing
        Using responseStream As IO.Stream = response.GetResponseStream
            'loop to read & write to file
            Using fs As New IO.FileStream(localfileamc, IO.FileMode.Create)
                Dim buffer(2047) As Byte
                Dim read As Integer = 0
                Dim count As Integer
                Do
                    If amcworker.CancellationPending = True Then
                        e.Cancel = True
                        Return
                    End If
                    StopWatch.Start()
                    amcworker.ReportProgress(CShort(count / Length * 100 + 0.5))
                    read = responseStream.Read(buffer, 0, buffer.Length)
                    fs.Write(buffer, 0, read)
                    count += read
                Loop Until read = 0
                StopWatch.Stop()
                responseStream.Close()
                fs.Flush()
                fs.Close()
            End Using
            responseStream.Close()
        End Using
        response.Close()
    Catch ex As Exception
        MessageBox.Show("An error has occurred during the process:" & vbCrLf & vbCrLf & ex.Message & vbCrLf & vbCrLf & "Please close the application and try again." _
                        & vbCrLf & "If you continue to encounter this error please Email")
        myProcessamc_Exited()
    End Try
    Installamc()
End Sub

'Starts the installation
Sub Installamc()
    startamc.StartInfo.FileName = "C:\AMC.exe"
    startamc.EnableRaisingEvents = True
    Try
        startamc.Start()
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
    Dispatcher.Invoke(New Action(AddressOf Progressamc_Hide))
End Sub
'Hide Dialog during install
Private Sub Progressamc_Hide()
    progressamc.Hide()
End Sub

'Report progress 
Private Sub amcworker_ProgressChanged(ByVal sender As System.Object, ByVal e As ComponentModel.ProgressChangedEventArgs) Handles amcworker.ProgressChanged
    ProgressBarAMC.value = e.ProgressPercentage
    blprgrsAMC.Content = "Downloading: " & e.ProgressPercentage & "%"
End Sub

End Class

再次,非常感谢任何帮助。

编辑:我对代码进行了以下编辑,但我并不完全确定它正在做我认为正在做的事情。基本上我的意图是ReportProgress只读取每2047字节运行一次。

'Get the response to the Ftp request and the associated stream
    Try
        Dim response As System.Net.FtpWebResponse = CType(FTP.GetResponse, System.Net.FtpWebResponse)
        Dim Length As Long = response.ContentLength
        Dim StopWatch As New Stopwatch
        Dim CurrentSpeed As Double = Nothing
        Using responseStream As IO.Stream = response.GetResponseStream
            'loop to read & write to file
            Using fs As New IO.FileStream(localfileamc, IO.FileMode.Create)
                Dim buffer(2047) As Byte
                Dim read As Integer = 0
                Dim count As Integer
                Dim chunk As Integer = Int(2047 / Length)
                Dim cycle As Integer = chunk = count
                Do
                    If amcworker.CancellationPending = True Then
                        e.Cancel = True
                        Return
                    End If
                    StopWatch.Start()
                    If cycle = True Then
                        amcworker.ReportProgress(CShort(count / Length * 100 + 0.5))
                    Else
                        End
                    End If
                    read = responseStream.Read(buffer, 0, buffer.Length)
                    fs.Write(buffer, 0, read)
                    count += read
                Loop Until read = 0
                StopWatch.Stop()
                responseStream.Close()
                fs.Flush()
                fs.Close()
            End Using
            responseStream.Close()
        End Using
        response.Close()
    Catch ex As Exception
        MessageBox.Show("An error has occurred during the process:" & vbCrLf & vbCrLf & ex.Message & vbCrLf & vbCrLf & "Please close the application and try again." _
                        & vbCrLf & "If you continue to encounter this error please Email")
        myProcessamc_Exited()
    End Try

1 个答案:

答案 0 :(得分:1)

我没有仔细仔细检查代码,但我不明白你为什么要使用秒表,所以我拿出了参考资料。我不确定在循环内多次启动它并在外面结束它会做什么。

在第二个示例中使用单词END将完全结束您的应用程序!很确定那就是你想要的。

尝试修改您的第一个代码。如果更改为> = 5%:

,则仅更新密钥
       Using fs As New IO.FileStream(localfileamc, IO.FileMode.Create)
            Dim buffer(2047) As Byte
            Dim read As Integer = 0
            Dim count As Integer
            dim LastPct as Short = -5
            dim Pct as Short = 0 
            Do
                If amcworker.CancellationPending = True Then
                    e.Cancel = True
                    Return
                End If
                Pct = CShort(count / Length * 100 + 0.5)
                if Pct>= (LastPct + 5)
                    amcworker.ReportProgress(Pct)
                    LastPCT= Pct
                EndIf
                read = responseStream.Read(buffer, 0, buffer.Length)
                fs.Write(buffer, 0, read)
                count += read
            Loop Until read = 0
            amcworker.ReportProgress(100)
            responseStream.Close()
            fs.Flush()
            fs.Close()
        End Using