Avatar billede steensommer Praktikant
09. februar 2015 - 10:38 Der er 11 kommentarer

Progressbar

Hej

Før opstart af en lidt "gumpetungt" windowsform har jeg lavet en Form med en Progressbar.
Alt fungerer fint BORTSET fra at selve progressbaren ikke bevæger sig før det "tunge" arbejde er udført i baggrunden.
Hvordan kan jeg få Progressbaren til at køre mens det øvrige arbejde udføres?


Public Class FrmProgresbar
    Private Sub ProgressBar1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ProgressBar1.Click

    End Sub

    Private Sub FrmProgressbar_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        ProgressBar1.Value += 5
        If ProgressBar1.Value = 100 Then
            Timer1.Stop()
            ProgressBar1.Value = 0
            With FrmPatientliste
                If .ToolStripTextBox1.Text = "tv2" Then
                    .Visible = False
                    FrmOpgaver.Show()
                ElseIf FrmPatientliste.ToolStripTextBox1.Text = "tv1" Then
                    .Visible = False
                    FrmPatientflade.Show()
                Else
                    .WindowState = FormWindowState.Maximized
                    .Visible = True
                End If
            End With
            Me.Close()
        End If
    End Sub
End Class
Avatar billede Mads Larsen Nybegynder
09. februar 2015 - 14:18 #1
Tror du har brug for at køre "det tunge arbejde" i en thread for sig selv, så den ikke fryser din GUI thread.

(Den nemme udgave kunne være background worker)

I første omgang kunne du prøve at smide denne ind i din Tick

Application.DoEvents() - så skulle den gerne refresh GUI billedet.
Avatar billede steensommer Praktikant
09. februar 2015 - 15:37 #2
Har allerede testet: Application.DoEvents()  ...men sammen resultat.
Jeg har desuden de sidste timer for første gang prøvet at arbejde med Background Worker men det kniber nu med at få det til at fungere :-/
Avatar billede arne_v Ekspert
09. februar 2015 - 19:23 #3
Jeg har et eksempel med traad og invoke:


Imports System
Imports System.Drawing
Imports System.IO
Imports System.Net
Imports System.Windows.Forms
Imports System.Threading

Public Class MainForm
Inherits Form
    Private bar As ProgressBar
    Private start As Button
    Private abort As Button
    Private t As Thread
    Public Sub New()
        bar = New ProgressBar
        start = New Button
        abort = New Button
        SuspendLayout
        bar.Location = New Point(50, 50)
        bar.Size = New Size(200, 50)
        bar.Name = "Progress Bar"
        start.Location = New Point(50, 150)
        start.Size = New Size(200, 50)
        start.Name = "Start Button"
        start.Text = "Start"
        AddHandler start.Click, AddressOf StartClick
        abort.Location = New Point(50, 250)
        abort.Size = New Size(200, 50)
        abort.Name = "Abort Button"
        abort.Text = "Abort"
        AddHandler abort.Click, AddressOf AbortClick
        ClientSize = New Size(300, 350)
        Controls.Add(bar)
        Controls.Add(start)
        Controls.Add(abort)
        Name = "Main Form"
        Text = "Main Form"
        ResumeLayout(False)
    End Sub
    Sub ResetBar(ByVal n As Integer)
        bar.Minimum = 0
        bar.Maximum = n
        bar.Value = 0
    End Sub
    Sub UpdateBar(ByVal n As Integer)
        bar.Value = n
    End Sub
    Delegate Sub ResetHandler(ByVal n As Integer)
    Delegate Sub UpdateHandler(ByVal n As Integer)
    Sub Copy()
        Try
        Dim req As HttpWebRequest = CType(WebRequest.Create("http://wasd.vsm.com.au/wasd/wasd1020.zip"), HttpWebRequest)
        Dim resp As HttpWebResponse = CType(req.GetResponse, HttpWebResponse)
        Dim tot As Integer = CType(resp.ContentLength, Integer)
        If bar.InvokeRequired Then
            bar.Invoke(DirectCast(Sub() ResetBar(tot), Action))
        Else
            ResetBar(tot)
        End If
        Dim f1 As Stream = resp.GetResponseStream
        Dim f2 As Stream = New FileStream("C:\work\wasd1020.zip", FileMode.Create, FileAccess.Write)
        Dim sofar As Integer = 0
        Dim b(1000) As Byte
        Dim n As Integer
        Do
            n = f1.Read(b, 0, b.Length)
            If n < 0 Then Exit Do
            f2.Write(b, 0, n)
            sofar += n
            If bar.InvokeRequired Then
                bar.Invoke(DirectCast(Sub() UpdateBar(sofar), Action))
            Else
                UpdateBar(sofar)
            End If
        Loop
        f2.Close
        f1.Close
        resp.Close
        Catch ex As Exception
        MessageBox.Show(ex.Message)
        End Try
    End Sub
    Sub StartClick(ByVal sender As Object, ByVal e As EventArgs)
        t = New Thread(AddressOf Copy)
        t.Start
    End Sub
    Sub AbortClick(ByVal sender As Object, ByVal e As EventArgs)
        t.Abort
    End Sub
    <STAThread()> _
    Public Shared Sub Main(ByVal args As String())
        Application.Run(New MainForm)
        Application.Exit
        Environment.Exit(0)
    End Sub
End Class
Avatar billede steensommer Praktikant
10. februar 2015 - 08:58 #4
Prøvede lige din løsning og fik følgende 2 fejl (samme fejl 2 steder):

Expression expected fejl ved:
bar.Invoke(DirectCast(Sub() UpdateBar(sofar), Action))
Avatar billede steensommer Praktikant
10. februar 2015 - 12:01 #5
Fejl ved: "Sub"
Avatar billede arne_v Ekspert
10. februar 2015 - 14:54 #6
Hvilken version af .NET/Visual Studio bruger du?
Avatar billede steensommer Praktikant
10. februar 2015 - 15:06 #7
.net 2.0 og Visual Basic 2008
Avatar billede arne_v Ekspert
10. februar 2015 - 15:21 #8
Det er lidt gammelt.

Men jeg har samme kode i en aeldre udgave ogsaa.


Imports System
Imports System.Drawing
Imports System.IO
Imports System.Net
Imports System.Windows.Forms
Imports System.Threading

Public Class MainForm
Inherits Form
    Private bar As ProgressBar
    Private start As Button
    Private abort As Button
    Private t As Thread

    Public Sub New()
        bar = New ProgressBar
        start = New Button
        abort = New Button
        SuspendLayout
        bar.Location = New Point(50, 50)
        bar.Size = New Size(200, 50)
        bar.Name = "Progress Bar"
        start.Location = New Point(50, 150)
        start.Size = New Size(200, 50)
        start.Name = "Start Button"
        start.Text = "Start"
        AddHandler start.Click, AddressOf StartClick
        abort.Location = New Point(50, 250)
        abort.Size = New Size(200, 50)
        abort.Name = "Abort Button"
        abort.Text = "Abort"
        AddHandler abort.Click, AddressOf AbortClick
        ClientSize = New Size(300, 350)
        Controls.Add(bar)
        Controls.Add(start)
        Controls.Add(abort)
        Name = "Main Form"
        Text = "Main Form"
        ResumeLayout(False)
    End Sub
    Sub ResetBar(ByVal n As Integer)
        bar.Minimum = 0
        bar.Maximum = n
        bar.Value = 0
    End Sub
    Sub UpdateBar(ByVal n As Integer)
        bar.Value = n
    End Sub
    Delegate Sub ResetHandler(ByVal n As Integer)
    Delegate Sub UpdateHandler(ByVal n As Integer)
    Sub Copy()
        Try
        Dim req As HttpWebRequest = CType(WebRequest.Create("http://wasd.vsm.com.au/wasd/htroot913.zip"), HttpWebRequest)
        Dim resp As HttpWebResponse = CType(req.GetResponse, HttpWebResponse)
        Dim tot As Integer = CType(resp.ContentLength, Integer)
        If bar.InvokeRequired Then
            bar.Invoke(New ResetHandler(AddressOf ResetBar), New Object() {tot})
        Else
            ResetBar(tot)
        End If
        Dim f1 As Stream = resp.GetResponseStream
        Dim f2 As Stream = New FileStream("C:\htroot913.zip", FileMode.CreateNew, FileAccess.Write)
        Dim sofar As Integer = 0
        Dim b(1000) As Byte
        Dim n As Integer
        n = f1.Read(b, 0, b.Length)
        While n > 0
            f2.Write(b, 0, n)
            sofar += n
            If bar.InvokeRequired Then
                bar.Invoke(new UpdateHandler(AddressOf UpdateBar), New Object() {sofar})
            Else
                UpdateBar(sofar)
            End If
            n = f1.Read(b, 0, b.Length)
        End While
        f2.Close
        f1.Close
        resp.Close
        Catch ex As Exception
        MessageBox.Show(ex.Message)
        End Try
    End Sub
    Sub StartClick(ByVal sender As Object, ByVal e As EventArgs)
        t = New Thread(AddressOf Copy)
        t.Start
    End Sub
    Sub AbortClick(ByVal sender As Object, ByVal e As EventArgs)
        t.Abort
    End Sub
    <STAThread()> _
    Public Shared Sub Main(ByVal args As String())
        Application.Run(New MainForm)
        Application.Exit
        Environment.Exit(0)
    End Sub
End Class
Avatar billede steensommer Praktikant
10. februar 2015 - 15:53 #9
Nu spørger jeg rigtig dumt ...hvordan tester jeg lige den?
Avatar billede arne_v Ekspert
16. februar 2015 - 02:18 #10
Du kan bygge kommando prompt.

Eller copy paste relevant kode ind i et VS projeckt.
Avatar billede steensommer Praktikant
16. februar 2015 - 09:21 #11
Jeg har kopieret koden ind men når jeg normalt vil afvikle en kode eller vise en form så skriver jeg:

"Frmform.show" eller i stil med "KodeTilSub" men det kan jeg åbenbart ikke i dette tilfælde!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester