none
WinForm下实现拷贝大文件,并且用滚动条显示当前拷贝进度,并且当页面切换出去回来时,仍然可以显示进度条 RRS feed

  • 问题

  • 请教各位前辈:(代码块可以略过不看)

    目前已经实现的功能:当前页面通过ProgressBar显示进度条。

    实现的代码思路:上传文件时,开辟一条子线程,然后子线程中通过委托修改主线程UI界面的ProgressBar的值,代码如下:

    public void CopyFile(string fromPath, string toPath, int eachReadLength)
            {
                Task.Factory.StartNew(() =>
                {  
                    FileStream fromFile = new FileStream(fromPath, FileMode.Open, FileAccess.Read);
                    FileStream toFile = new FileStream(toPath, FileMode.Create, FileAccess.Write);
                    
                    int toCopyLength = 0;
                    if (eachReadLength < fromFile.Length)
                    {
                        byte[] buffer = new byte[eachReadLength];
                        long copied = 0;
                        while (copied <= fromFile.Length - eachReadLength)
                        {
                            toCopyLength = fromFile.Read(buffer, 0, eachReadLength);
                            fromFile.Flush();
                            toFile.Write(buffer, 0, eachReadLength);
                            toFile.Flush();
                            toFile.Position = fromFile.Position;
                            copied += toCopyLength;
                            try
                            {
                                MethodInvoker mi = new MethodInvoker(() =>
                                {
                                    prg_UpFile.Maximum = (int)fromFile.Length;
                                    prg_UpFile.Value = (int)copied;
                                });
                                this.BeginInvoke(mi);
                            }
                            catch
                            {
                                continue;
                            }
                        }
                        int left = (int)(fromFile.Length - copied);
                        toCopyLength = fromFile.Read(buffer, 0, left);
                        fromFile.Flush();
                        toFile.Write(buffer, 0, left);
                        toFile.Flush();
                    }
                    else
                    {
                        byte[] buffer = new byte[fromFile.Length];
                        fromFile.Read(buffer, 0, buffer.Length);
                        fromFile.Flush();
                        toFile.Write(buffer, 0, buffer.Length);
                        toFile.Flush();
                    }
                    fromFile.Close();
                    toFile.Close();
                    return true;
                });            
            }


    函数思路是:通过流的拷贝来实现文件拷贝,然后while循环中可以获取到已拷贝文件的字节数,通过委托来实现修改UI界面。

    接下来要实现的内容:点击其他页面再切回来,仍然可以看到进度条进度。

    存在的问题:

    ①测试过,当切换到其他页面时,拷贝线程仍然存在,但是线程中的委托失效了

    我理解错误原因在于是,线程存在时,界面上并不存在委托修改的ProgressBar,因此对于委托进行try catch{continue}处理,但是这种方式仍然无效

    ②另外一种方式

    切换后,重新加载到当前页面后,开辟一个线程,去拷贝线程中获取已拷贝文件的字节数,通过委托修改界面,这种方法不知道是否可行,而且我不知道怎么去子线程中不断的获取到值。

    ③由于页面时嵌入到其他程序的,因为对于修改页面外层框架不太现实,只能考虑单个页面加载,单个页面关闭的情况。


    2019年9月17日 1:38

全部回复

  • Hi FakeFrame,

    你可以尝试使用BackGroundWorker来执行拷贝操作,然后再使用ReportProgress方法更新进度条。下面是一简单示例,你可以参考一下。

        private BackgroundWorker worker;
    
        public Form1()
        {
            InitializeComponent();
            worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.ProgressChanged += worker_ProgressChanged;
            worker.DoWork += worker_DoWork;
            worker.RunWorkerAsync();
        }
    
        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            for(int i = 0;i<= 100000;i++)
            {
                worker.ReportProgress(i/1000);
            }
        }
    
        private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.BeginInvoke((MethodInvoker)delegate
            {
                progressBar1.Value = e.ProgressPercentage;
            });
        }

    你可以参考一下文档 BackgroundWorker Class。希望这些能帮到你。

    Regards,

    Kyle


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2019年9月17日 6:31
    版主
  • 为啥不换个思路,切换页面的时候只是隐藏当前进度页面,切换回来的时候再显示;

    本来这个拷贝进度不停止的化就是应该一直都在(比如windows的拷贝,你切换到其他应用程序,他还是在哪里拷贝的);


    family as water

    2019年9月19日 2:05