如何将进度条与进程同步

How to sync progress bar with process

我目前正在创建一个可在控制台上运行的文件复制工具。其中存在 3 个基本 classes,第一个是程序本身,它采用源和目标,如下所示:

 class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Source:");
            string path = Console.ReadLine();

            Console.WriteLine("target:");

            string target = Console.ReadLine();


            Copy newCopy = new Copy();
            newCopy.CopyFunction(path, target);

            Console.ReadLine();
        }
    }

第二个class是Copy.CS如下:

class Copy

    {
        public void CopyFunction(string source, string destination)
        {
            string sourceFile = source;
            string destinationFile = destination;

            File.Copy(sourceFile, destinationFile);

            Console.Write("Files are being copied... ");
            using (var progress = new ProgressBar())
            {
                for (int i = 0; i <= 100; i++)
                {
                    progress.Report((double)i / 100);
                    Thread.Sleep(20);
                }
            }

            Console.WriteLine("File Copied");         

        }

    }

对于最后的class,我实现了@DanielWolf

提供的ProgressBar.csclass

https://gist.github.com/DanielSWolf/0ab6a96899cc5377bf54

我目前遇到的问题是文件复制功能可以,进度条也可以,但是它们是分开工作的。例如,控制台在处理正在发生的事情时会在空白屏幕上停留一段时间,然后在完成后,显示进度条的快速动画。

我想知道是否可以将进度条与复制过程同步,以便它在复制过程中以相似的速度移动?

要实现您的目标,您需要在复制文件时更新进度条。一种方法是简单地按块复制文件并在复制每个块时报告进度。我修改了你的 CopyFunction 来做到这一点。享受吧!

class Copy

{
    public void CopyFunction(string sourcePath, string destinationPath)
    {
        byte[] buffer = new byte[1024 * 10]; // 10K buffer, you can change to larger size.

        using (var progress = new ProgressBar())
        using (FileStream source = new FileStream(sourcePath, FileMode.Open, FileAccess.Read))
        {
            long fileLength = source.Length;
            using (FileStream dest = new FileStream(destinationPath, FileMode.Create, FileAccess.Write))
            {
                long totalBytes = 0;
                int currentBlockSize = 0;

                while ((currentBlockSize = source.Read(buffer, 0, buffer.Length)) > 0)
                {
                    totalBytes += currentBlockSize;
                    dest.Write(buffer, 0, currentBlockSize);
                    progress.Report((double)totalBytes / fileLength);

                }
                progress.Report((double)1.0);
            }

            //File.Copy(sourceFile, destinationFile);

            //Console.Write("Files are being copied... ");
            //using (var progress = new ProgressBar())
            //{
            //    for (int i = 0; i <= 100; i++)
            //    {
            //        progress.Report((double)i / 100);
            //        Thread.Sleep(20);
            //    }
            //}

            Console.WriteLine("File Copied");

        }
    }
}