我在获取进度条以显示下载进度时遇到问题。这些文件正在下载,没有问题,但是由于某些原因导致进度条无法更新,所以我不知道为什么。
我尝试在download
和wc_DownloadProgressChanged
方法中手动设置progressBar值,但实际上更改的唯一地方是Form1_Load
方法。
using System;
using System.Windows.Forms;
using System.Threading;
namespace Launch
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Downloader downloader = new Downloader();
ThreadStart job = new ThreadStart(downloader.download);
Thread thread = new Thread(job);
thread.Start();
}
private void ProgressBar_Click(object sender, EventArgs e)
{
}
public void SetProgress(int val)
{
progressBar.Value = val;
}
public void SetVisible(bool val)
{
progressBar.Visible = val;
}
}
}
using System;
using System.Data;
using System.Net;
using Newtonsoft.Json;
namespace Launch
{
class Downloader
{
public void download()
{
WebClient client = new WebClient();
string url = "https://someurl.com/manifest.json";
string json = client.DownloadString(url);
DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(json);
DataTable dataTable = dataSet.Tables["Required"];
foreach (DataRow row in dataTable.Rows)
{
string remoteUri = row["url"].ToString();
string fileName = row["name"].ToString();
client.DownloadProgressChanged += client_DownloadProgressChanged;
client.DownloadFile(remoteUri, fileName);
Console.WriteLine("Did something with " + remoteUri);
}
}
private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
var form = new Form1();
form.SetProgress(e.ProgressPercentage);
}
}
}
任何人都可以对我在这里做错的事情有所了解吗?
编辑:
我可以使用DownloadFileAsync
来使大部分正常工作,但是我认为进度条是来回跳动的,因为它正在尝试计算进度每个单独的文件都以字节为单位,因此我想使用DownloadFile来完成此工作。
DownloadFile现在遇到的问题是我将其作为任务运行,但是它跳过了所有文件(不下载任何文件,只是将它们全部打印出来以超快的速度进行控制台)。
这是我当前正在使用的代码:
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
string url = "https://someurl.com/manifest.json";
string json = client.DownloadString(url);
DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(json);
DataTable dataTable = dataSet.Tables["Required"];
foreach (DataRow row in dataTable.Rows)
{
string remoteUri = row["url"].ToString();
string fileName = row["name"].ToString();
Task.Run(() => {
client.DownloadFile(remoteUri, fileName);
});
Console.WriteLine("Did something with " + remoteUri);
}
}
private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate {
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
label1.Text = "Downloaded ";
label2.Text = e.BytesReceived.ToString();
label3.Text = e.TotalBytesToReceive.ToString();
progressBar.Value = int.Parse(Math.Truncate(percentage).ToString());
});
}
有什么想法吗?
答案 0 :(得分:0)
在下面使用此代码:
private void Form1_Load(object sender, EventArgs e)
{
WebClient client = new WebClient();
client.DownloadProgressChanged += client_DownloadProgressChanged;
client.DownloadStringCompleted += client_DownloadStringCompleted;
Uri url = new Uri("url");
client.DownloadStringAsync(url);
}
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
SetVisible(false);
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
SetProgress(e.ProgressPercentage);
}
public void SetProgress(int val)
{
progressBar.Value = val;
}
public void SetVisible(bool val)
{
progressBar.Visible = val;
}
答案 1 :(得分:0)
这可能应该属于https://codereview.stackexchange.com/
首先,不要在循环中添加处理程序
client.DownloadProgressChanged += client_DownloadProgressChanged;
第一次可以,在第二项上将被称为2倍,在第三次上将被称为3次,依此类推。您想要设置一次处理程序。将其移动到行之后:
WebClient client = new WebClient();
第二,每次触发进度更新时,您都在创建表单的新实例。一次创建一个私有变量或属性。
private Form1 form = new Form1();
对于UI,通常只能在创建它的调度程序线程中进行修改或使用封送处理。我将其删除,因为我们已经下载了字符串async。
此外,我不会使用e.ProgressPercentage,而是类似:
Math.Truncate(e.BytesReceived / (double)e.TotalBytesToReceive * 100)