BackgroundWorker and ProgressBar
-
I want to display the status in a ProgressBar when copying large files across the network. I am using FileInfo.CopyTo method within the DoWork Method of the BackgroundWorker class (please see the code below). How am I able to fire events while the copying is taking place to update the ProgressBar. The problem is that the execution enters FileInfo.CopyTo method and does not leave until the process is complete. Hope this makes sense.
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; reached = 0; fileInfoFrom = new FileInfo(@"C:\Temp\Path1\Test.zip"); fileInfoTo = new FileInfo(@"C:\Temp\Path2\Test.zip"); fs = (fileInfoTo.Exists) ? fileInfoTo.Length : 0f; fileInfoFrom.CopyTo(@"C:\Temp\Path2\Test.zip", true); /* thought about using the file size to * calculate the percentage for the progressbar*/ int completed = (int)((float)fs / (float)fileInfoFrom.Length * 100); if (completed > reached) { reached = completed; worker.ReportProgress(completed); } }
-- modified at 12:47 Sunday 4th December, 2005 -
I want to display the status in a ProgressBar when copying large files across the network. I am using FileInfo.CopyTo method within the DoWork Method of the BackgroundWorker class (please see the code below). How am I able to fire events while the copying is taking place to update the ProgressBar. The problem is that the execution enters FileInfo.CopyTo method and does not leave until the process is complete. Hope this makes sense.
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; reached = 0; fileInfoFrom = new FileInfo(@"C:\Temp\Path1\Test.zip"); fileInfoTo = new FileInfo(@"C:\Temp\Path2\Test.zip"); fs = (fileInfoTo.Exists) ? fileInfoTo.Length : 0f; fileInfoFrom.CopyTo(@"C:\Temp\Path2\Test.zip", true); /* thought about using the file size to * calculate the percentage for the progressbar*/ int completed = (int)((float)fs / (float)fileInfoFrom.Length * 100); if (completed > reached) { reached = completed; worker.ReportProgress(completed); } }
-- modified at 12:47 Sunday 4th December, 2005Well, the way I'd tackle it would be to implement the File Copy function myself. I could raise events with controlled frequency as I shovel the data from the source file to the new destination file. Regards, Rob Philpott.
-
Well, the way I'd tackle it would be to implement the File Copy function myself. I could raise events with controlled frequency as I shovel the data from the source file to the new destination file. Regards, Rob Philpott.
-
Hi, I've cobbled together an implementation you can use to get you started. Please note this is rough and ready and has no Exception handling in it etc. Ideally, to do the job properly I'd implement a new class and provide
BeginCopy
,CancelCopy
andEndCopy
static methods as we are encouraged to do for asynchronous methods. BTW - because you will launch the copy on a worker thread, make sure you switch thread before attempting to update your progress bar (useControl.BeginInvoke
).using System; using System.Collections.Generic; using System.Text; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { FileCopy(@"f:\BTSDev Hard Disk.vhd", @"c:\test.vhd", new UpdateProgressDelegate(RelayProgress)); } public static void RelayProgress(int percentile) { Console.WriteLine("{0}% complete", percentile); } delegate void UpdateProgressDelegate(int percentile); static void FileCopy(string sourceFileName, string destinationFileName, UpdateProgressDelegate handler) { byte[] buffer = new byte[1024]; FileStream fsInput = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read); FileStream fsOutput = new FileStream(destinationFileName, FileMode.Create, FileAccess.Write); long totalLength = fsInput.Length; long readSoFar = 0; int percentile = 0; // send the 0%
-
Hi, I've cobbled together an implementation you can use to get you started. Please note this is rough and ready and has no Exception handling in it etc. Ideally, to do the job properly I'd implement a new class and provide
BeginCopy
,CancelCopy
andEndCopy
static methods as we are encouraged to do for asynchronous methods. BTW - because you will launch the copy on a worker thread, make sure you switch thread before attempting to update your progress bar (useControl.BeginInvoke
).using System; using System.Collections.Generic; using System.Text; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { FileCopy(@"f:\BTSDev Hard Disk.vhd", @"c:\test.vhd", new UpdateProgressDelegate(RelayProgress)); } public static void RelayProgress(int percentile) { Console.WriteLine("{0}% complete", percentile); } delegate void UpdateProgressDelegate(int percentile); static void FileCopy(string sourceFileName, string destinationFileName, UpdateProgressDelegate handler) { byte[] buffer = new byte[1024]; FileStream fsInput = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read); FileStream fsOutput = new FileStream(destinationFileName, FileMode.Create, FileAccess.Write); long totalLength = fsInput.Length; long readSoFar = 0; int percentile = 0; // send the 0%
-
Thank you, that makes sense. Do you think this method would be slower than the FileInfo or File classes? I am sure thaey use a very similar method within those classes. Thank you once again. Will be implementing the method.
Hi, No problem, glad to be of help :) Performace wise I'd expect the Framework methods to have the edge as they use unmanaged Win32 calls behind the scenes (probably the reason asynchronous methods aren't provided for us). One thing you could do if the files you are copying are very big is to increase the size of the buffer from 1KB to say 8KB or more. Regards, Rob Philpott.