如何将进度条与流程同步

时间:2019-05-19 11:49:14

标签: c# console-application

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

 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();
        }
    }

第二个类是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");         

        }

    }

对于最后一个类,我实现了@DanielWolf提供的ProgressBar.cs类。

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

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

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

1 个答案:

答案 0 :(得分:2)

要实现所需的功能,您需要在复制文件时更新进度条。一种方法是简单地按块复制文件,并在复制每个块时报告进度。我修改了您的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");

        }
    }
}