【问题标题】:How to sync progress bar with process如何将进度条与进程同步
【发布时间】:2023-03-29 13:24:01
【问题描述】:

我目前正在创建一个在控制台上工作的文件复制工具。其中存在 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

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

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

【问题讨论】:

    标签: c# console-application


    【解决方案1】:

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

    【讨论】:

    • 顺便说一句,这个复制文件的功能会被认为是递归算法吗?我正在尝试理解这个概念
    • 查看重复机制。它是相同的方法名称,还是一种循环?在这种情况下,您可以看到有一个“while”循环,因此它不是递归。如果它自称它会随着数据集的缩小而一次又一次地重复出现(因此是递归)。数据必须变得“更小”,这样您最终才能达到足够“小”的大小,从而停止重复并给出直接结果。 (我引用小,因为它可能更大 - 但更接近退出条件)
    • @OriNachum 那么将罗伯特建议的复制函数变成递归算法是否可能/很难?
    • 它会 - 任何循环在技术上都可以是递归,但为什么呢?它不会给你任何优势。此操作本质上是线性的(您不想并行复制文件 - 一次随机块),因此递归没有任何目的。您应该知道尽可能避免递归,因为它们往往会消耗大量内存。
    • @OriNachum 我的任务是为复制文件创建一个递归算法,以确保我可以展示对它的理解。我不希望这需要递归,但我试图做到这一点只是因为它被要求作为要求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多