When kicking off an async job using backgroundworker, the process I tried
is a My.Computer.FileSystem.CopyDirectory(a,b). The next step is to
check the progress with bw.ReportProgress(x) but that statement doesn't get
control until the copydirectory finishes. I'm not new to programming but to
this backgroundworker. Any help would be appreciated. Thank you.

Recommended Answers

All 9 Replies

There is no way to report the progress of a single statement operation like My.Computer.FileSystem.CopyDirectory(a,b) other than copy started and copy completed. If you want a progress report then you'll have to break up the operation into multiple single-file copies and report the file name and something like copying file 3 of 9 files. If you are copying sub-folders then you'll have to write your own recursive file copy.

You may be interested in a tutorial on background threads that I put together a few months ago. Among other things, it covers how to update form controls from a background thread.

commented: Good tutorial +6

I guess from all the examples I've seen, the only useful background process is to count to 30 or 100 and update a progress bar. Anything anyone would like to accomplish is along the lines of a single statement operation. I'm giving up on backgroundprocess. I started with a recursive file copy and it worked great, just slower than I wanted. Thank you.

Copying files in the foreground could make your application unresponsive. When running in the background, be aware that updating progress too frequently will have a performance impact on your operation. If only showing a progress bar, you may consider not updating every iteration, but rather every few iterations.

For i as Integer = 0 to 100

    If i Mod 5 = 0 Then
        'report progress

    End If
Next

I was wandering if, maybe, first a total size of the files to be copied could be obtained. Then, we could make an estimation e= Kb copied/second and, why not?, the main thread could show the progress bar, for example, each second a rate:
time elapsed (seconds) / e

Sorry, the % should be:
% = size_to_copy x (1/e) x time_elapsed / 100
[in dimensions: %(dimensionless) = (KB) x (seconds/KB) x (seconds) ]

To be exact, KB and seconds are units, but the units must be coherent, of course. % = [size] x [T]/[size] x [T]
wiki

Lets put down an example. If total size to copy, S, is 100 MegaBytes:
S= 100 M
Estimated speed, e, is 5 Megabytes per second:
e= 5M/s
When the elapsed time, t, is 1 second, copied % will be:
% = 1 second x 5M/s / 100 M x 100 = 5%
At t=5seconds:
% = 5 seconds x 5M/s / 100M x 100 = 25%
At t=20 seconds:
% = 20 seconds x 5M/s / 100M x 100 = 100%
If there is no mistake and assuming transfer rate is 5M/s, in 20 seconds the progress bar would be at 100%. I think its very clear that the estimation will always be an approximation and varies along time and from one machine to another.

Well, there is a solution consisting in examing the destiny's folder size while the backgroundworker thread is executing. Attached is a sample. Uses a thread instance, instead, but to the case makes no difference. The main process enters a loop which ends when all the source files have been copied, i.e., destination size >= source files size. Meanwhile, gets the destination size and updates the progress bar:

    Private Sub btnCopy_Click(sender As Object, e As EventArgs) Handles btnCopy.Click
        Try
            Me.enableDisBtns(False)
            If Me.nFase = 0 Then
                MsgBox("First click button to create files.")
                Exit Sub
            End If
            Me.enableDisBtns(False)
            totalSrcSize = getSrcSize()
            Dim t As New Thread(AddressOf cpyFiles)
            t.Start()
            Dim totalDstSize As Long = getDirSize(dstPath)
            Do While totalDstSize < totalSrcSize
                DspProgBar(CInt(totalDstSize * 100 / totalSrcSize)) ' dsp progress
                Application.DoEvents()
                totalDstSize = getDirSize(dstPath)
            Loop
            DspProgBar(CInt(totalDstSize * 100 / totalSrcSize))
            MsgBox("Copy has ended.")
            Me.nFase = 0
            DspProgBar(0)
        Catch ex As Exception
            MsgBox(ex.ToString)
        Finally
            Me.enableDisBtns(True)
        End Try
    End Sub
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.