在RunWorkerCompleted触发后,BackgroundWorker OnProgressChanged仍然触发

Api*_*iet 2 c# backgroundworker progress-bar

我的应用程序用于BackgroundWorker将文件上传到FTP服务器.一切正常,但似乎OnProgressChanged事件不应该像它应该的那样工作.

事件发生OnProgressChanged后我会完全完成RunWorkerCompleted,但事实并非如此.

在我的情况下,OnProgressChanged虽然RunWorkerComplete被触发,事件仍在触发.显然,我的进度条仍在继续,而我的文件已经完全发送到ftp服务器.

我在我的调试模式下进行了测试,我看到在RunWorkerCompletedFired 之后,OnPorgressChanged仍在工作.

我的代码在这里.

 void FTP_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker bw = sender as BackgroundWorker;
        try
        {
            string filename = e.Argument.ToString();
            if (filename != string.Empty)
            { 
                FileInfo fileInf = new FileInfo(filename);
                FtpWebRequest reqFTP;
                if (!IsFolderExist(_defaultDir))
                {
                    MakeDefaultDir(_defaultDir);
                }

                reqFTP = GetRequest(this._host, this._port, GetDirName(_defaultDir) + "/" + fileInf.Name, this._user, this._pass);
                reqFTP.KeepAlive = false;
                reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
                reqFTP.UseBinary = true;
                reqFTP.ContentLength = fileInf.Length;

                long FileSize = fileInf.Length;
                string FileSizeDescription = GetFileSize(FileSize);



                int ChunkSize = 4096, NumRetries = 0, MaxRetries = 50;
                long SentBytes = 0;
                byte[] Buffer = new byte[ChunkSize]; 
                int BytesRead = 0;


                using (Stream requestStream = reqFTP.GetRequestStream())
                {

                    using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                         BytesRead = fs.Read(Buffer, 0, ChunkSize); // read the first chunk in the buffer
                        while (BytesRead > 0)
                        {
                            try
                            {
                                if (bw.CancellationPending)
                                    return;

                                requestStream.Write(Buffer, 0, BytesRead);


                                SentBytes += BytesRead;

                                // Here is progress information
                                string SummaryText = String.Format("Transferred {0} / {1}", GetFileSize(SentBytes), FileSizeDescription);
                                bw.ReportProgress((int)(((decimal)SentBytes / (decimal)FileSize) * 100), SummaryText);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("Exception: " + ex.ToString());
                                if (NumRetries++ < MaxRetries)
                                {
                                    fs.Position -= BytesRead;
                                }
                                else
                                {
                                    throw new Exception(String.Format("Error occurred during upload, too many retries. \n{0}", ex.ToString()));
                                }
                            }
                            BytesRead = fs.Read(Buffer, 0, ChunkSize);  
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            if (OnFTPError != null)
            {
                OnFTPError(this, "Error was handled in Replaced File Uploading :" + ex.Message);
            }
        }     
    }
Run Code Online (Sandbox Code Playgroud)

关于这个问题的任何想法?多谢你们

Han*_*ant 7

这很可能是由Vista更新为本机进度条组件引入的工件引起的,该组件也出现在Windows 7中.要查看它,请启动一个新的Winforms项目并在表单上放置一个进度条和一个按钮.双击该按钮,使Click事件处理程序如下所示:

    private void button1_Click(object sender, EventArgs e) {
        if (progressBar1.Value == progressBar1.Maximum) progressBar1.Value = progressBar1.Minimum;
        else progressBar1.Value = progressBar1.Maximum;
    }
Run Code Online (Sandbox Code Playgroud)

按F5并单击按钮.注意条形图是如何动画的,它从0平滑移动到100.大约需要一秒钟.

也许你现在看到了这个含义,这个动画产生了滞后.换句话说,可见值总是小于编程值,除非你给它足够的时间来赶上.你没有,你不断用ProgressChanged事件处理程序更新值.

不幸的是,他们忘了提供关闭此动画的选项.然而,有一个技巧,默认情况下,动画被禁用为减量.您可以做的是将Value属性设置两次,首先设置为值+ 1,然后设置为值.条形图立即跳转到编程值.唯一的缺陷是你不能轻易跳到100%.