e.ProgressPercentage returns 0-50



i具有以下代码来监视上传过程。我正在使用e.ProgressPercentage跟踪当前的进度,但是它返回错误的值。

using (WebClient client = new WebClient())
{
    client.Credentials = new NetworkCredential(DataIO.FTP.Username, DataIO.FTP.Password);
    Uri uri = new Uri($"ftp://{DataIO.FTP.Server}/{DataIO.FTP.UploadDir}/{DataIO.SelectedOutputArchive}.tar.gz");
    client.UploadProgressChanged += new UploadProgressChangedEventHandler(delegate (object s2, UploadProgressChangedEventArgs e2) {
        ProgressLabel.Invoke((MethodInvoker)delegate
        {
            ProgressLabel.Text = $"{(e2.BytesSent / 1024).ToString()} KB / {(e2.TotalBytesToSend / 1024).ToString()} KB";
        });
        UploadProgressBar.Invoke((MethodInvoker)delegate
        {
            UploadProgressBar.Value = e2.ProgressPercentage; // returns 0-50
            //UploadProgressBar.Value = (int)Clamp((float)e2.ProgressPercentage / 50 * 100, 0, 100);
        });
        Debug.WriteLine(e2.ProgressPercentage);
    });
    client.UploadFileCompleted += new UploadFileCompletedEventHandler(delegate {
        this.Invoke((MethodInvoker)delegate
        {
            this.Text = "Upload: Success";
        });
        Thread.Sleep(2000);
        this.Invoke((MethodInvoker)delegate
        {
            this.Close();
        });
    });
    client.UploadFileAsync(uri, "STOR", localFilePath);
}

我尝试在输出窗口中调试它,返回的值就是这样:

0
0
1
0
1
0
1
1
1
2
2
1
2
2
3
3
2
3
3
...
49
49
50
49
100
49
49

这些后跳不一定很重要,但是从49跳到100是。

我以为它总是在0-50之间返回(意识到它的提高50之后(。因此,我需要将其扩展到0-100。这起作用了,但随后从49跃升至100。缩放期望从0-50开始,并收到100次中断(导致溢出结果(200(,ProgressBar期望为0-100(。然后,我不得不夹紧结果值。所以我想到了:

(int)Clamp((float)e2.ProgressPercentage / 50 * 100, 0, 100)

虽然现在正常工作,但我想知道为什么我需要破解使它起作用的方式。我做错了吗?


更新:我决定不依靠e.ProgressPercentage并自己进行计算:

UploadProgressBar.Value = (int)(e2.BytesSent / (float)e2.TotalBytesToSend * 100);

这是设计。原因是

上传时,服务器也可以作为对上传的响应发送数据。通常,对于任何HTTP请求,这都是正确的。考虑上传一堆输入的表单,然后服务器发送一堆数据,也许是SQL Server数据库报告。 在所有这些情况下,我们将上载并下载为50%和50%。 因此,如果服务器未发送任何数据,则它将直接跳到50到100

来源:https://social.msdn.microsoft.com/forums/en-us/9ab5a1b4-c30d-4dbb-bbb-bebe-a00ef8e72029/problems-webclientupploploasync?forumeasync?forum=netfxnetfxnetfxnetcom 检查此线程是否有此方法可能的问题。

另一种解决方案

可视化上载的正确值的另一个选项是使用uploadprogresschangedeventargs对象的另外两个属性 - bytessent,totalbytestosend-并自己进行计算。作为参考,请检查示例部分。

编辑:我找不到记录以这种方式实施此目的的任何地方,但是这里是负责此行为的代码:

        private void PostProgressChanged(AsyncOperation asyncOp, ProgressData progress) {
        if (asyncOp != null && progress.BytesSent + progress.BytesReceived > 0)
        {
            int progressPercentage;
            if (progress.HasUploadPhase)
            {
                if (progress.TotalBytesToReceive < 0 && progress.BytesReceived == 0)
                {
                    progressPercentage = progress.TotalBytesToSend < 0 ? 0 : progress.TotalBytesToSend == 0 ? 50 : (int)((50 * progress.BytesSent) / progress.TotalBytesToSend);
                }
                else
                {
                    progressPercentage = progress.TotalBytesToSend < 0 ? 50 : progress.TotalBytesToReceive == 0 ? 100 : (int) ((50 * progress.BytesReceived) / progress.TotalBytesToReceive + 50);
                }
                asyncOp.Post(reportUploadProgressChanged, new UploadProgressChangedEventArgs(progressPercentage, asyncOp.UserSuppliedState, progress.BytesSent, progress.TotalBytesToSend, progress.BytesReceived, progress.TotalBytesToReceive));
            }
            else
            {
                progressPercentage = progress.TotalBytesToReceive < 0 ? 0 : progress.TotalBytesToReceive == 0 ? 100 : (int) ((100 * progress.BytesReceived) / progress.TotalBytesToReceive);
                asyncOp.Post(reportDownloadProgressChanged, new DownloadProgressChangedEventArgs(progressPercentage, asyncOp.UserSuppliedState, progress.BytesReceived, progress.TotalBytesToReceive));
            }
        }
    }

来源:https://referencesource.microsoft.com/system/net/system/net/webclient.cs.html#2966

我也能够再现相同的重现,包括奇怪的滴。

考虑使用来自单独线程的FtpWebRequest。这样,您可以完全控制上传进度。

请参阅我的答案我们如何显示进度栏以使用ftpwebrequest上传。

相关内容

  • 没有找到相关文章

最新更新