BackgroundWorker UI和Progress问题

时间:2018-04-19 00:57:01

标签: vb.net backgroundworker

所以我一直在摆弄这个问题,我不知道我是不是在理解BackgroundWorker是如何工作的和/或我错误地使用它,或者我是不是#39;我遗漏了什么。

基本上我尝试做的是从DragDrop函数调用BackgroundWorker,用户可以将一组图像放入表单中。然后BackgroundWorder将图像复制到临时位置,拉伸缩略图并将其转换为PictureBoxes,并将PictureBox添加到集合中。完成BackgroundWorker后,该函数将运行以将所有图片框添加到表单中。

除了进展之外,所有这些都正常工作。在此过程中,进度功能不会直到最后(在几乎所有图片都被复制之后)才会触发(此时我确定进度功能不是为什么不是我无法弄清楚UI锁定的原因。

我已逐步完成代码,并且ReportProgress方法被称为ever循环,但ProgressReported函数不会被调用,直到接近结束。

HELP! LOL

这是我复制和创建缩略图的ControlClass

Imports System.ComponentModel
Imports System.IO

Namespace ThumbnailViewer

    Public Class ThumbnailControl
        Inherits FlowLayoutPanel

        Private ImageExtensions As List(Of String) = New List(Of String) From {".JPG", ".JPE", ".BMP", ".GIF", ".PNG"}
        Private tempStoragePath As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) & "\tempPhotos"
        Private WithEvents bkWPhotos As New BackgroundWorker
        Public Property iThumbList As List(Of PictureBox)
        Public Property sImageList As List(Of String(,))
        Private PopupPrg As PopUpProgress.PopUpProgressControl

        Public Sub New()
            Me.AutoScroll = True
            Me.AllowDrop = True
            Me.DoubleBuffered = True
            iThumbList = New List(Of PictureBox)()
            sImageList = New List(Of String(,))()
            AddHandler Me.DragDrop, AddressOf ThumbnailViewerControl_DragDrop
            AddHandler Me.DragEnter, AddressOf ThumbnailViewerControl_DragEnter
            If Not Directory.Exists(tempStoragePath) Then Directory.CreateDirectory(tempStoragePath)
            bkWPhotos.WorkerReportsProgress = True
            bkWPhotos.WorkerSupportsCancellation = True
        End Sub

        Public Sub BackGroundWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bkWPhotos.DoWork
            AddImage(e.Argument)
        End Sub

        Public Sub BackGroundWorkder_Progress(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles bkWPhotos.ProgressChanged
            PopupPrg.SetProgress(e.ProgressPercentage)
        End Sub

        Public Sub BackGroundWorker_Complete(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles bkWPhotos.RunWorkerCompleted
            For Each i As PictureBox In iThumbList
                Me.Controls.Add(i)
            Next
            PopupPrg.Destory()
            Me.Cursor = Cursors.Default
        End Sub

        Public Sub AddImage(ByVal files As String())
            Dim fImage As Image

            Dim prg As Integer = 0
            For Each f As String In files
                If ImageExtensions.Contains(Path.GetExtension(f).ToUpperInvariant()) Then
                    bkWPhotos.ReportProgress(prg)
                    fImage = Image.FromFile(f)
                    File.Copy(f, tempStoragePath & "\" & Path.GetFileName(f), True)
                    sImageList.Add({{tempStoragePath & "\" & Path.GetFileName(f), fImage.Size.Width, fImage.Size.Height}})
                    Dim t As PictureBox = MakeThumbnail(fImage)
                    prg = prg + 1
                    GC.GetTotalMemory(True)
                End If
            Next
        End Sub

        Public Function MakeThumbnail(ByVal inImage As Image) As PictureBox
            Dim thumb As PictureBox = New PictureBox()
            thumb.Size = ScaleImage(inImage.Size, 200)
            thumb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
            thumb.SizeMode = PictureBoxSizeMode.Zoom
            AddHandler thumb.MouseEnter, AddressOf thumb_MouseEnter
            AddHandler thumb.MouseLeave, AddressOf thumb_MouseLeave
            AddHandler thumb.DoubleClick, AddressOf thumb_DoubleClick
            thumb.Image = inImage.GetThumbnailImage(thumb.Width - 2, thumb.Height - 2, Nothing, New IntPtr())
            iThumbList.Add(thumb)
            Return thumb
        End Function

        Private Sub thumb_DoubleClick(ByVal sender As Object, ByVal e As EventArgs)
            Dim previewForm As Form = New Form()
            Dim index As Integer = Me.Controls.GetChildIndex(CType(sender, PictureBox))
            Dim img As Image = Image.FromFile(sImageList(index)(0, 0))
            previewForm.FormBorderStyle = FormBorderStyle.SizableToolWindow
            previewForm.MinimizeBox = False
            previewForm.Size = ScaleImage(img.Size, Screen.GetWorkingArea(Me).Height / 4 * 3)
            previewForm.StartPosition = FormStartPosition.CenterScreen
            Dim view As PictureBox = New PictureBox()
            view.Dock = DockStyle.Fill
            view.Image = Image.FromFile(sImageList(index)(0, 0))
            view.SizeMode = PictureBoxSizeMode.Zoom
            previewForm.Controls.Add(view)
            previewForm.ShowDialog()
        End Sub

        Private Sub thumb_MouseLeave(ByVal sender As Object, ByVal e As EventArgs)
            CType(sender, PictureBox).Invalidate()
        End Sub

        Private Sub thumb_MouseEnter(ByVal sender As Object, ByVal e As EventArgs)
            Dim rc = (CType(sender, PictureBox)).ClientRectangle
            rc.Inflate(-2, -2)
            ControlPaint.DrawBorder((CType(sender, PictureBox)).CreateGraphics(), (CType(sender, PictureBox)).ClientRectangle, Color.Red, ButtonBorderStyle.Solid)
            ControlPaint.DrawBorder3D((CType(sender, PictureBox)).CreateGraphics(), rc, Border3DStyle.Bump)
        End Sub

        Private Sub ThumbnailViewerControl_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs)
            If e.Data.GetDataPresent(DataFormats.FileDrop) Then e.Effect = DragDropEffects.Copy Else e.Effect = DragDropEffects.None
        End Sub

        Private Sub ThumbnailViewerControl_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs)
            If e.Data.GetDataPresent(DataFormats.FileDrop) Then
                Dim files As String() = CType(e.Data.GetData(DataFormats.FileDrop), String())
                Me.Cursor = Cursors.WaitCursor
                PopupPrg = New PopUpProgress.PopUpProgressControl(Me, files.Count)
                bkWPhotos.RunWorkerAsync(files)
            End If
        End Sub

        Public Function ScaleImage(ByVal oldImage As Size, ByVal TargetHeight As Integer) As Size
            Dim NewHeight As Integer = TargetHeight
            Dim NewWidth As Integer = NewHeight / oldImage.Height * oldImage.Width
            NewHeight = NewWidth / oldImage.Width * oldImage.Height
            Return New Size(NewWidth, NewHeight)
        End Function

    End Class

End Namespace

1 个答案:

答案 0 :(得分:1)

.... FacePalm.. I figured it out. Apparently during my testing (before I decided to use this control and a background worker, I had added another drag drop function in another area of my code that was being called first. It was taking all the dragged images and turning them into Image data types. The rest of the function was commented out which is why I didn't notice it before because I was only stepping though the classes functions not the functions in the main UI. but it makes perfect sense now, the backgroundworker and the UI function were kicking off at the same time but while the UI thread was processing the Image data typing the report progress calls were stacking up.

After removing that secondary function it works exactly as it should, UI remains fully functional Images and PictureBoxes are processed in the background and the Progressbar updates properly and remains functional as well.