Progress Bar makes copying painfully slow, a little help please?
-
I've implemented a progress bar to my application but it makes the file copy process painfully slow whereas without the progress bar the copy is very fast. I know without the progress bar it only takes a few seconds to copy a 10 megabyte file but with the progress bar it takes more than a minute. What am I doing wrong?
namespace Compression_Util
{
class DropBox
{
private object sender;
private EventArgs e;
private DragEventArgs de;
private Design zip;
private string hover;
private string[] files;
private string filetype;public DropBox(object sender, DragEventArgs de, Design zip, string hover) { this.sender = sender; this.de = de; this.zip = zip; this.hover = hover; this.Hover(); } public DropBox(object sender, EventArgs e, Design zip, string hover) { this.sender = sender; this.e = e; this.zip = zip; this.hover = hover; this.Hover(); } private void InitializeProgressBar(int fileSize) { zip.DropProgress.Visible = true; zip.DropProgress.Minimum = sizeof(Byte); zip.DropProgress.Step = sizeof(Byte); zip.DropProgress.Maximum = fileSize; } private void DeInitializeProgressBar() { zip.DropProgress.Invalidate(); zip.DropProgress.Visible = false; } private void IncrementProgressBar() { zip.DropProgress.PerformStep(); } private void CreateFile(string read, string write) { try { FileStream fileStreamReader = new FileStream(read, FileMode.Open, FileAccess.Read); FileStream fileStreamWriter = new FileStream(write, FileMode.Create, FileAccess.ReadWrite); BinaryReader binaryReader = new BinaryReader(fileStreamReader); BinaryWriter binaryWriter = new BinaryWriter(fileStreamWriter); int position = 0; int length = (int)binaryReader.BaseStream.Length; InitializeProgressBar(length); while (position < length) { Byte line = binaryReader.ReadByte(); binaryWriter.Write(line); position += sizeof(Byte); Increm
-
I've implemented a progress bar to my application but it makes the file copy process painfully slow whereas without the progress bar the copy is very fast. I know without the progress bar it only takes a few seconds to copy a 10 megabyte file but with the progress bar it takes more than a minute. What am I doing wrong?
namespace Compression_Util
{
class DropBox
{
private object sender;
private EventArgs e;
private DragEventArgs de;
private Design zip;
private string hover;
private string[] files;
private string filetype;public DropBox(object sender, DragEventArgs de, Design zip, string hover) { this.sender = sender; this.de = de; this.zip = zip; this.hover = hover; this.Hover(); } public DropBox(object sender, EventArgs e, Design zip, string hover) { this.sender = sender; this.e = e; this.zip = zip; this.hover = hover; this.Hover(); } private void InitializeProgressBar(int fileSize) { zip.DropProgress.Visible = true; zip.DropProgress.Minimum = sizeof(Byte); zip.DropProgress.Step = sizeof(Byte); zip.DropProgress.Maximum = fileSize; } private void DeInitializeProgressBar() { zip.DropProgress.Invalidate(); zip.DropProgress.Visible = false; } private void IncrementProgressBar() { zip.DropProgress.PerformStep(); } private void CreateFile(string read, string write) { try { FileStream fileStreamReader = new FileStream(read, FileMode.Open, FileAccess.Read); FileStream fileStreamWriter = new FileStream(write, FileMode.Create, FileAccess.ReadWrite); BinaryReader binaryReader = new BinaryReader(fileStreamReader); BinaryWriter binaryWriter = new BinaryWriter(fileStreamWriter); int position = 0; int length = (int)binaryReader.BaseStream.Length; InitializeProgressBar(length); while (position < length) { Byte line = binaryReader.ReadByte(); binaryWriter.Write(line); position += sizeof(Byte); Increm
kiasta wrote:
What am I doing wrong?
You're performing UI operations during the copy. What you should instead do is use a BackgroundWorker[^] to perform the file copy and publish UI updates. /ravi
My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com
-
I've implemented a progress bar to my application but it makes the file copy process painfully slow whereas without the progress bar the copy is very fast. I know without the progress bar it only takes a few seconds to copy a 10 megabyte file but with the progress bar it takes more than a minute. What am I doing wrong?
namespace Compression_Util
{
class DropBox
{
private object sender;
private EventArgs e;
private DragEventArgs de;
private Design zip;
private string hover;
private string[] files;
private string filetype;public DropBox(object sender, DragEventArgs de, Design zip, string hover) { this.sender = sender; this.de = de; this.zip = zip; this.hover = hover; this.Hover(); } public DropBox(object sender, EventArgs e, Design zip, string hover) { this.sender = sender; this.e = e; this.zip = zip; this.hover = hover; this.Hover(); } private void InitializeProgressBar(int fileSize) { zip.DropProgress.Visible = true; zip.DropProgress.Minimum = sizeof(Byte); zip.DropProgress.Step = sizeof(Byte); zip.DropProgress.Maximum = fileSize; } private void DeInitializeProgressBar() { zip.DropProgress.Invalidate(); zip.DropProgress.Visible = false; } private void IncrementProgressBar() { zip.DropProgress.PerformStep(); } private void CreateFile(string read, string write) { try { FileStream fileStreamReader = new FileStream(read, FileMode.Open, FileAccess.Read); FileStream fileStreamWriter = new FileStream(write, FileMode.Create, FileAccess.ReadWrite); BinaryReader binaryReader = new BinaryReader(fileStreamReader); BinaryWriter binaryWriter = new BinaryWriter(fileStreamWriter); int position = 0; int length = (int)binaryReader.BaseStream.Length; InitializeProgressBar(length); while (position < length) { Byte line = binaryReader.ReadByte(); binaryWriter.Write(line); position += sizeof(Byte); Increm
Not only are you copying the file in the UI, you are updating the progress bar every IO. I always calculate percent complete using the following formula: (number of bytes copied * 100) / size of file in bytes All numbers used in the calculation are long but the result is converted to int. Update the progress bar only when the percent changes.
-
I've implemented a progress bar to my application but it makes the file copy process painfully slow whereas without the progress bar the copy is very fast. I know without the progress bar it only takes a few seconds to copy a 10 megabyte file but with the progress bar it takes more than a minute. What am I doing wrong?
namespace Compression_Util
{
class DropBox
{
private object sender;
private EventArgs e;
private DragEventArgs de;
private Design zip;
private string hover;
private string[] files;
private string filetype;public DropBox(object sender, DragEventArgs de, Design zip, string hover) { this.sender = sender; this.de = de; this.zip = zip; this.hover = hover; this.Hover(); } public DropBox(object sender, EventArgs e, Design zip, string hover) { this.sender = sender; this.e = e; this.zip = zip; this.hover = hover; this.Hover(); } private void InitializeProgressBar(int fileSize) { zip.DropProgress.Visible = true; zip.DropProgress.Minimum = sizeof(Byte); zip.DropProgress.Step = sizeof(Byte); zip.DropProgress.Maximum = fileSize; } private void DeInitializeProgressBar() { zip.DropProgress.Invalidate(); zip.DropProgress.Visible = false; } private void IncrementProgressBar() { zip.DropProgress.PerformStep(); } private void CreateFile(string read, string write) { try { FileStream fileStreamReader = new FileStream(read, FileMode.Open, FileAccess.Read); FileStream fileStreamWriter = new FileStream(write, FileMode.Create, FileAccess.ReadWrite); BinaryReader binaryReader = new BinaryReader(fileStreamReader); BinaryWriter binaryWriter = new BinaryWriter(fileStreamWriter); int position = 0; int length = (int)binaryReader.BaseStream.Length; InitializeProgressBar(length); while (position < length) { Byte line = binaryReader.ReadByte(); binaryWriter.Write(line); position += sizeof(Byte); Increm
To add to what the others say, you are also doing this byte by byte! Buffer it: allocate a buffer of say 1/2 meg and fill it. Write it, update progress. Fill it, write it, update progress. But I do it in a background worker like this:
/// <summary> /// Do the actual file move. /// </summary> /// <param name="src"></param> /// <param name="dst"></param> /// <param name="worker"></param> /// <param name="prMain"></param> private void MoveFile(string src, string dst, BackgroundWorker worker = null, ProgressReport prMain = null) { if (src != dst) { // Copy the file itself. int iSrc = src.IndexOf(':'); int iDst = dst.IndexOf(':'); FileInfo fiSrc = new FileInfo(src); if (fiSrc.Length < blockSize || (iSrc > 0 && iDst > 0 && iSrc == iDst && src.Substring(0, iSrc) == dst.Substring(0, iDst))) { // On same drive or trivial size - move it via the file system if (doCopyOnly) { File.Copy(src, dst); } else { File.Move(src, dst); } } else { // Needs to be moved "properly". using (Stream sr = new FileStream(src, FileMode.Open)) { using (Stream sw = new FileStream(dst, FileMode.Create)) { long total = sr.Length; long bytes = 0; long cnt = total; int progress = 0; while (cnt > 0) { int n = sr.Read(transfer, 0, blockSize); sw.Write(transfer, 0, n); bytes += n; cnt -= n; int percent = (int)((bytes \* 100) / total); if (progress != percent) { // Report progress
-
kiasta wrote:
What am I doing wrong?
You're performing UI operations during the copy. What you should instead do is use a BackgroundWorker[^] to perform the file copy and publish UI updates. /ravi
My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com
-
Not only are you copying the file in the UI, you are updating the progress bar every IO. I always calculate percent complete using the following formula: (number of bytes copied * 100) / size of file in bytes All numbers used in the calculation are long but the result is converted to int. Update the progress bar only when the percent changes.
-
To add to what the others say, you are also doing this byte by byte! Buffer it: allocate a buffer of say 1/2 meg and fill it. Write it, update progress. Fill it, write it, update progress. But I do it in a background worker like this:
/// <summary> /// Do the actual file move. /// </summary> /// <param name="src"></param> /// <param name="dst"></param> /// <param name="worker"></param> /// <param name="prMain"></param> private void MoveFile(string src, string dst, BackgroundWorker worker = null, ProgressReport prMain = null) { if (src != dst) { // Copy the file itself. int iSrc = src.IndexOf(':'); int iDst = dst.IndexOf(':'); FileInfo fiSrc = new FileInfo(src); if (fiSrc.Length < blockSize || (iSrc > 0 && iDst > 0 && iSrc == iDst && src.Substring(0, iSrc) == dst.Substring(0, iDst))) { // On same drive or trivial size - move it via the file system if (doCopyOnly) { File.Copy(src, dst); } else { File.Move(src, dst); } } else { // Needs to be moved "properly". using (Stream sr = new FileStream(src, FileMode.Open)) { using (Stream sw = new FileStream(dst, FileMode.Create)) { long total = sr.Length; long bytes = 0; long cnt = total; int progress = 0; while (cnt > 0) { int n = sr.Read(transfer, 0, blockSize); sw.Write(transfer, 0, n); bytes += n; cnt -= n; int percent = (int)((bytes \* 100) / total); if (progress != percent) { // Report progress
The main objective is to compress the files into a container, but I want to at least be able to copy files with some type of progress notification at the very least first before I start making an algorithm for compression. Thanks for the source I'll study it and try to make something work.
-
Hmm OK that makes some sense, but why would copying it inside the UI make any difference? Without the progress bar the files copy very fast, almost instantly. I don't really understand, I guess. Is the progress bar really that resource intensive?
As you said, the progress bar slows down the copy. The progress bar is CPU intensive while the file copy is most likely IO bound. The progress bar slows the copy when the two operations share the same thread. Copying the file in a separate thread will allow more efficient use of multiple processors; both operations run almost independently. Also, try copying a file several gigabytes in size and watch your UI lock up. I tend to reuse code a lot. Code a process right the first time and use it many times.
-
As you said, the progress bar slows down the copy. The progress bar is CPU intensive while the file copy is most likely IO bound. The progress bar slows the copy when the two operations share the same thread. Copying the file in a separate thread will allow more efficient use of multiple processors; both operations run almost independently. Also, try copying a file several gigabytes in size and watch your UI lock up. I tend to reuse code a lot. Code a process right the first time and use it many times.